// Copyright (c) Microsoft Corporation.  All Rights Reserved.  See License.txt in the project root for license information.

namespace Microsoft.FSharp.Collections

open System
open Microsoft.FSharp.Core
open Microsoft.FSharp.Collections

/// <summary>Contains operations for working with arrays.</summary>
///
/// <remarks>
///  See also <a href="https://learn.microsoft.com/dotnet/fsharp/language-reference/arrays">F# Language Guide - Arrays</a>.
/// </remarks>
[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
[<RequireQualifiedAccess>]
module Array =

    /// <summary>Returns a new array that contains all pairings of elements from the first and second arrays.</summary>
    ///
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    ///
    /// <returns>The resulting array of pairs.</returns>
    ///
    /// <example id="all-pairs-1">
    /// <code lang="fsharp">
    /// ([| 1; 2 |], [| 3; 4 |]) ||> Array.allPairs
    /// </code>
    /// Evaluates to
    /// <code>
    /// [| (1, 3); (1, 4); (2, 3); (2, 4) |]
    /// </code>
    /// </example>
    [<CompiledName("AllPairs")>]
    val allPairs: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array

    /// <summary>Builds a new array that contains the elements of the first array followed by the elements of the second array.</summary>
    ///
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <returns>The resulting array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    ///
    /// <example id="append-1">
    /// <code lang="fsharp">
    /// Array.append [| 1; 2 |] [| 3; 4 |]
    /// </code>
    /// Evaluates to <c>[| 1; 2; 3; 4 |]</c>.
    /// </example>
    [<CompiledName("Append")>]
    val append: array1: 'T array -> array2: 'T array -> 'T array

    /// <summary>Returns the average of the elements in the array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when <c>array</c> is empty.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The average of the elements in the array.</returns>
    ///
    /// <example id="average-1">
    /// <code lang="fsharp">
    /// [| 1.0; 2.0; 6.0 |] |> Array.average
    /// </code>
    /// Evaluates to <c>3.0</c>
    /// </example>
    ///
    /// <example id="average-2">
    /// <code lang="fsharp">
    /// [| |] |> Array.average
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Average")>]
    val inline average:
        array: ^T array -> ^T
            when ^T: (static member (+): ^T * ^T -> ^T)
            and ^T: (static member DivideByInt: ^T * int -> ^T)
            and ^T: (static member Zero: ^T)

    /// <summary>Returns the average of the elements generated by applying the function to each element of the array.</summary>
    ///
    /// <param name="projection">The function to transform the array elements before averaging.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when <c>array</c> is empty.</exception>
    ///
    /// <returns>The computed average.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="average-by-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: float }
    ///
    /// let input = [| {Bar = 2.0}; {Bar = 4.0} |]
    ///
    /// input |> Array.averageBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to <c>3.0</c>
    /// </example>
    ///
    /// <example id="average-by-2">
    /// <code lang="fsharp">
    /// type Foo = { Bar: float }
    ///
    /// let input : Foo array = [| |]
    ///
    /// input |> Array.averageBy (fun foo -> foo.Bar)
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("AverageBy")>]
    val inline averageBy:
        projection: ('T -> ^U) -> array: 'T array -> ^U
            when ^U: (static member (+): ^U * ^U -> ^U)
            and ^U: (static member DivideByInt: ^U * int -> ^U)
            and ^U: (static member Zero: ^U)

    /// <summary>Reads a range of elements from the first array and write them into the second.</summary>
    ///
    /// <param name="source">The source array.</param>
    /// <param name="sourceIndex">The starting index of the source array.</param>
    /// <param name="target">The target array.</param>
    /// <param name="targetIndex">The starting index of the target array.</param>
    /// <param name="count">The number of elements to copy.</param>
    ///
    /// <remarks>
    /// Slicing syntax is generally preferred, e.g.
    /// <code lang="fsharp">
    /// let source = [| 12; 13; 14 |]
    /// let target = [| 0; 1; 2; 3; 4; 5 |]
    /// target[3..4] &lt;- source[1..2]
    /// </code>
    /// </remarks>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when any of sourceIndex, targetIndex or count are negative,
    /// or when there aren't enough elements in source or target.</exception>
    ///
    /// <example id="blit-1">
    /// <code lang="fsharp">
    /// let source = [| 12; 13; 14 |]
    /// let target = [| 0; 1; 2; 3; 4; 5 |]
    ///
    /// Array.blit source 1 target 3 2
    /// </code>
    /// After evaluation <c>target</c> contains <c>[| 0; 1; 2; 13; 14; 5 |]</c>.
    /// </example>
    [<CompiledName("CopyTo")>]
    val inline blit: source: 'T array -> sourceIndex: int -> target: 'T array -> targetIndex: int -> count: int -> unit

    /// <summary>For each element of the array, applies the given function. Concatenates all the results and return the combined array.</summary>
    ///
    /// <param name="mapping">The function to create sub-arrays from the input array elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The concatenation of the sub-arrays.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="collect-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: int array }
    ///
    /// let input = [| {Bar = [| 1; 2 |]}; {Bar = [| 3; 4 |]} |]
    ///
    /// input |> Array.collect (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to <c>[| 1; 2; 3; 4 |]</c>
    /// </example>
    ///
    /// <example id="collect-2">
    /// <code lang="fsharp">
    /// let input = [[1; 2]; [3; 4]]
    ///
    /// input |> Array.collect id
    /// </code>
    /// Evaluates to <c>[| 1; 2; 3; 4 |]</c>
    /// </example>
    [<CompiledName("Collect")>]
    val collect: mapping: ('T -> 'U array) -> array: 'T array -> 'U array

    /// <summary>Compares two arrays using the given comparison function, element by element.</summary>
    ///
    /// <param name="comparer">A function that takes an element from each array and returns an int.
    /// If it evaluates to a non-zero value iteration is stopped and that value is returned.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <returns>Returns the first non-zero result from the comparison function. If the first array has
    /// a larger element, the return value is always positive. If the second array has a larger
    /// element, the return value is always negative. When the elements are equal in the two
    /// arrays, 1 is returned if the first array is longer, 0 is returned if they are equal in
    /// length, and -1 is returned when the second array is longer.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays
    /// is null.</exception>
    ///
    /// <example id="compare-with-1">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [| 1; 10 |]
    /// let input2 = [| 1; 10 |]
    ///
    /// (input1, input2) ||> Array.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>0</c>
    /// </example>
    ///
    /// <example id="compare-with-2">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [| 1; 5 |]
    /// let input2 = [| 1; 8 |]
    ///
    /// (input1, input2) ||> Array.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>-1</c>
    /// </example>
    ///
    /// <example id="compare-with-3">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [| 1; 11 |]
    /// let input2 = [| 1; 13 |]
    ///
    /// (input1, input2) ||> Array.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="compare-with-4">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [| 1; 2 |]
    /// let input2 = [| 1 |]
    ///
    /// (input1, input2) ||> Array.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="compare-with-5">
    /// <code lang="fsharp">
    /// let closerToNextDozen a b =
    ///   (a % 12).CompareTo(b % 12)
    ///
    /// let input1 = [| 1 |]
    /// let input2 = [| 1; 2 |]
    ///
    /// (input1, input2) ||> Array.compareWith closerToNextDozen
    /// </code>
    /// Evaluates to <c>-1</c>
    /// </example>
    [<CompiledName("CompareWith")>]
    val inline compareWith: comparer: ('T -> 'T -> int) -> array1: 'T array -> array2: 'T array -> int

    /// <summary>Builds a new array that contains the elements of each of the given sequence of arrays.</summary>
    ///
    /// <param name="arrays">The input sequence of arrays.</param>
    ///
    /// <returns>The concatenation of the sequence of input arrays.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="concat-1">
    /// <code lang="fsharp">
    /// let inputs = [ [| 1; 2 |]; [| 3 |]; [| 4; 5 |] ]
    ///
    /// inputs |> Array.concat
    /// </code>
    /// Evaluates to <c>[| 1; 2; 3; 4; 5 |]</c>
    /// </example>
    [<CompiledName("Concat")>]
    val concat: arrays: seq<'T array> -> 'T array

    /// <summary>Tests if the array contains the specified element.</summary>
    ///
    /// <param name="value">The value to locate in the input array.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>True if the input array contains the specified element; false otherwise.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="contains-1">
    /// <code lang="fsharp">
    /// [| 1; 2 |] |> Array.contains 2 // evaluates to true
    /// [| 1; 2 |] |> Array.contains 5 // evaluates to false
    /// </code>
    /// </example>
    [<CompiledName("Contains")>]
    val inline contains: value: 'T -> array: 'T array -> bool when 'T: equality

    /// <summary>Builds a new array that contains the elements of the given array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>A copy of the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="copy-1">
    /// <code lang="fsharp">
    /// let source = [| 12; 13; 14 |]
    ///
    /// Array.copy source
    /// </code>
    /// Evaluates to a new array containing<c>[| 12; 13; 14 |]</c>.
    /// </example>
    [<CompiledName("Copy")>]
    val copy: array: 'T array -> 'T array

    /// <summary>Applies a key-generating function to each element of an array and returns an array yielding unique
    /// keys and their number of occurrences in the original array.</summary>
    ///
    /// <param name="projection">A function transforming each item of the input array into a key to be
    /// compared against the others.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="count-by-1">
    /// <code lang="fsharp">
    /// type Foo = { Bar: string }
    ///
    /// let inputs = [| {Bar = "a"}; {Bar = "b"}; {Bar = "a"} |]
    ///
    /// inputs |> Array.countBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to <c>[| ("a", 2); ("b", 1) |]</c>
    /// </example>
    [<CompiledName("CountBy")>]
    val countBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * int) array when 'Key: equality

    /// <summary>Creates an array whose elements are all initially the given value.</summary>
    ///
    /// <param name="count">The length of the array to create.</param>
    /// <param name="value">The value for the elements.</param>
    ///
    /// <returns>The created array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when count is negative.</exception>
    ///
    /// <example id="create-1">
    /// <code lang="fsharp">
    /// Array.create 4 "a"
    /// </code>
    /// Evaluates to a new array containing<c>[| "a"; "a"; "a"; "a" |]</c>.
    /// </example>
    ///
    /// <example id="create-2">
    /// <code lang="fsharp">
    /// let cell = ref "a"
    /// let array = Array.create 2 cell
    /// cell.Value &lt;- "b"
    ///
    /// </code>
    /// Before evaluation of the last line, <c>array</c> contains<c>[| { contents = "a"}; { contents = "a"} |]</c>.
    /// After evaluation of the last line <c>array</c> contains<c>[| { contents = "b"}; { contents = "b"} |]</c>.
    /// Note each entry in the array is the same mutable cell object.
    /// </example>
    [<CompiledName("Create")>]
    val create: count: int -> value: 'T -> 'T array

    /// <summary>Returns the first element of the array, or
    /// <c>None</c> if the array is empty.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The first element of the array or None.</returns>
    ///
    /// <example id="tryhead-1">
    /// <code lang="fsharp">
    /// let inputs = [| "banana"; "pear" |]
    ///
    /// inputs |> Array.tryHead
    /// </code>
    /// Evaluates to <c>Some "banana"</c>
    /// </example>
    ///
    /// <example id="tryhead-2">
    /// <code lang="fsharp">
    /// let inputs : int array = [| |]
    ///
    /// inputs |> Array.tryHead
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryHead")>]
    val tryHead: array: 'T array -> 'T option

    /// <summary>Applies the given function to successive elements, returning the first
    /// result where the function returns <c>Some(x)</c> for some <c>x</c>. If the function
    /// never returns <c>Some(x)</c> then <c>None</c> is returned.</summary>
    ///
    /// <param name="chooser">The function to transform the array elements into options.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The first transformed element that is <c>Some(x)</c>.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="trypick-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.tryPick (fun n -> if n % 2 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>Some "2"</c>.
    /// </example>
    ///
    /// <example id="trypick-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.tryPick (fun n -> if n > 3 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>None</c>.
    /// </example>
    ///
    [<CompiledName("TryPick")>]
    val tryPick: chooser: ('T -> 'U option) -> array: 'T array -> 'U option

    /// <summary>Fills a range of elements of the array with the given value.</summary>
    ///
    /// <param name="target">The target array.</param>
    /// <param name="targetIndex">The index of the first element to set.</param>
    /// <param name="count">The number of elements to set.</param>
    /// <param name="value">The value to set.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when either targetIndex or count is negative.</exception>
    ///
    /// <example id="fill-1">
    /// <code lang="fsharp">
    /// let target = [| 0; 1; 2; 3; 4; 5 |]
    ///
    /// Array.fill target 3 2 100
    /// </code>
    /// After evaluation <c>target</c> contains <c>[| 0; 1; 2; 100; 100; 5 |]</c>.
    /// </example>
    [<CompiledName("Fill")>]
    val fill: target: 'T array -> targetIndex: int -> count: int -> value: 'T -> unit

    /// <summary>Applies the given function to successive elements, returning the first
    /// result where the function returns <c>Some(x)</c> for some <c>x</c>. If the function
    /// never returns <c>Some(x)</c> then <see cref="T:System.Collections.Generic.KeyNotFoundException"/> is raised.</summary>
    ///
    /// <param name="chooser">The function to generate options from the elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if every result from
    /// <c>chooser</c> is <c>None</c>.</exception>
    ///
    /// <returns>The first result.</returns>
    ///
    /// <example id="pick-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.pick (fun n -> if n % 2 = 0 then Some (string n) else None)
    /// </code>
    /// Evaluates to <c>"2"</c>.
    /// </example>
    ///
    /// <example id="pick-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.pick (fun n -> if n > 3 = 0 then Some (string n) else None)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>.
    /// </example>
    ///
    [<CompiledName("Pick")>]
    val pick: chooser: ('T -> 'U option) -> array: 'T array -> 'U

    /// <summary>Applies the given function to each element of the array. Returns
    /// the array comprised of the results <c>x</c> for each element where
    /// the function returns <c>Some(x)</c></summary>
    ///
    /// <param name="chooser">The function to generate options from the elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array of results.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="choose-1">
    /// <code lang="fsharp">
    /// let input = [| Some 1; None; Some 2 |]
    ///
    /// input |> Array.choose id
    /// </code>
    /// Evaluates to <c>[| 1; 2 |]</c>
    /// </example>
    ///
    /// <example id="choose-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.choose (fun n -> if n % 2 = 0 then Some n else None)
    /// </code>
    /// Evaluates to <c>[| 2 |]</c>
    /// </example>
    [<CompiledName("Choose")>]
    val choose: chooser: ('T -> 'U option) -> array: 'T array -> 'U array

    /// <summary>Divides the input array into chunks of size at most <c>chunkSize</c>.</summary>
    ///
    /// <param name="chunkSize">The maximum size of each chunk.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array divided into chunks.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when <c>chunkSize</c> is not positive.</exception>
    ///
    /// <example id="chunk-by-size-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.chunkBySize 2
    /// </code>
    /// Evaluates to <c>[| [|1; 2|]; [|3|] |]</c>
    /// </example>
    ///
    /// <example id="chunk-by-size-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3 |]
    ///
    /// input |> Array.chunkBySize -2
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("ChunkBySize")>]
    val chunkBySize: chunkSize: int -> array: 'T array -> 'T array array

    /// <summary>Returns an array that contains no duplicate entries according to generic hash and
    /// equality comparisons on the entries.
    /// If an element occurs multiple times in the array then the later occurrences are discarded.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="distinct-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 1; 2; 3 |]
    ///
    /// input |> Array.distinct
    /// </code>
    /// Evaluates to <c>[| 1; 2; 3 |]</c>
    /// </example>
    [<CompiledName("Distinct")>]
    val distinct: array: 'T array -> 'T array when 'T: equality

    /// <summary>Returns an array that contains no duplicate entries according to the
    /// generic hash and equality comparisons on the keys returned by the given key-generating function.
    /// If an element occurs multiple times in the array then the later occurrences are discarded.</summary>
    ///
    /// <param name="projection">A function transforming the array items into comparable keys.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="distinct-by-1">
    /// <code lang="fsharp">
    /// let inputs = [| {Bar = 1 };{Bar = 1}; {Bar = 2}; {Bar = 3} |]
    ///
    /// inputs |> Array.distinctBy (fun foo -> foo.Bar)
    /// </code>
    /// Evaluates to <c>[| { Bar = 1 }; { Bar = 2 }; { Bar = 3 } |]</c>
    /// </example>
    [<CompiledName("DistinctBy")>]
    val distinctBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: equality

    /// <summary>Splits the input array into at most <c>count</c> chunks.</summary>
    ///
    /// <param name="count">The maximum number of chunks.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array split into chunks.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when <c>count</c> is not positive.</exception>
    ///
    /// <example id="split-into-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.splitInto 3
    /// </code>
    /// Evaluates to <c>seq [| [|1; 2|]; [|3; 4|]; [|5|] |]</c>
    /// </example>
    ///
    /// <example id="split-into-2">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.splitInto -1
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("SplitInto")>]
    val splitInto: count: int -> array: 'T array -> 'T array array

    /// <summary>Returns an empty array of the given type.</summary>
    /// <returns>The empty array.</returns>
    ///
    /// <example id="empty">
    /// <code lang="fsharp">
    /// Array.empty // Evaluates to [| |]
    /// </code>
    /// </example>
    [<GeneralizableValue>]
    [<CompiledName("Empty")>]
    val empty<'T> : 'T array

    /// <summary>Returns the only element of the array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The only element of the array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input does not have precisely one element.</exception>
    ///
    /// <example id="exactly-one-1">
    /// <code lang="fsharp">
    /// let inputs = [| "banana" |]
    ///
    /// inputs |> Array.exactlyOne
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="exactly-one-2">
    /// <code lang="fsharp">
    /// let inputs = [| "pear"; "banana" |]
    ///
    /// inputs |> Array.exactlyOne
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    ///
    /// <example id="exactly-one-3">
    /// <code lang="fsharp">
    /// let inputs: int array = [| |]
    ///
    /// inputs |> Array.exactlyOne
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("ExactlyOne")>]
    val exactlyOne: array: 'T array -> 'T

    /// <summary>Returns the only element of the array or <c>None</c> if array is empty or contains more than one element.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The only element of the array or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="try-exactly-one-1">
    /// <code lang="fsharp">
    /// let inputs = [| "banana" |]
    ///
    /// inputs |> Array.tryExactlyOne
    /// </code>
    /// Evaluates to <c>Some banana</c>
    /// </example>
    ///
    /// <example id="try-exactly-one-2">
    /// <code lang="fsharp">
    /// let inputs = [| "pear"; "banana" |]
    ///
    /// inputs |> Array.tryExactlyOne
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    ///
    /// <example id="try-exactly-one-3">
    /// <code lang="fsharp">
    /// let inputs: int array = [| |]
    ///
    /// inputs |> Array.tryExactlyOne
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryExactlyOne")>]
    val tryExactlyOne: array: 'T array -> 'T option

    /// <summary>Returns a new list with the distinct elements of the input array which do not appear in the itemsToExclude sequence,
    /// using generic hash and equality comparisons to compare values.</summary>
    ///
    /// <param name="itemsToExclude">A sequence whose elements that also occur in the input array will cause those elements to be
    /// removed from the result.</param>
    /// <param name="array">An array whose elements that are not also in itemsToExclude will be returned.</param>
    ///
    /// <returns>An array that contains the distinct elements of <c>array</c> that do not appear in <c>itemsToExclude</c>.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either itemsToExclude or array is null.</exception>
    ///
    /// <example id="except-1">
    /// <code lang="fsharp">
    /// let original = [| 1; 2; 3; 4; 5 |]
    /// let itemsToExclude = [| 1; 3; 5 |]
    ///
    /// original |> Array.except itemsToExclude
    /// </code>
    /// Evaluates to <c>[| 2; 4 |]</c>
    /// </example>
    [<CompiledName("Except")>]
    val except: itemsToExclude: seq<'T> -> array: 'T array -> 'T array when 'T: equality

    /// <summary>Tests if any element of the array satisfies the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to the elements of the input array. If any application
    /// returns true then the overall result is true and no further elements are tested.
    /// Otherwise, false is returned.</remarks>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>True if any result from <c>predicate</c> is true.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="exists-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3; 4; 5 |]
    ///
    /// input |> Array.exists (fun elm -> elm % 4 = 0)
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    ///
    /// <example id="exists-2">
    /// <code lang="fsharp">
    /// let input = [| 1; 2; 3; 4; 5 |]
    ///
    /// input |> Array.exists (fun elm -> elm % 6 = 0)
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    [<CompiledName("Exists")>]
    val inline exists: predicate: ('T -> bool) -> array: 'T array -> bool

    /// <summary>Tests if any pair of corresponding elements of the arrays satisfies the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to matching elements in the two collections up to the lesser of the
    /// two lengths of the collections. If any application returns true then the overall result is
    /// true and no further elements are tested. Otherwise, if one collections is longer
    /// than the other then the <c>ArgumentException</c> exception is raised.
    /// Otherwise, false is returned.</remarks>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <returns>True if any result from <c>predicate</c> is true.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <example id="exists2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| 1; 2 |]
    /// let inputs2 = [| 1; 2; 0 |]
    ///
    /// (inputs1, inputs2) ||> Array.exists2 (fun a b -> a > b)
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    ///
    /// <example id="exists2-2">
    /// <code lang="fsharp">
    /// let inputs1 = [| 1; 4 |]
    /// let inputs2 = [| 1; 3; 5 |]
    ///
    /// (inputs1, inputs2) ||> Array.exists2 (fun a b -> a > b)
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    [<CompiledName("Exists2")>]
    val exists2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool

    /// <summary>Returns a new collection containing only the elements of the collection
    /// for which the given predicate returns "true".</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>An array containing the elements for which the given predicate returns true.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="filter-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.filter (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>[| 2; 4 |]</c>
    /// </example>
    [<CompiledName("Filter")>]
    val filter: predicate: ('T -> bool) -> array: 'T array -> 'T array

    /// <summary>Returns the first element for which the given function returns 'true'.
    /// Raise <see cref="T:System.Collections.Generic.KeyNotFoundException"/> if no such element exists.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if <c>predicate</c>
    /// never returns true.</exception>
    ///
    /// <returns>The first element for which <c>predicate</c> returns true.</returns>
    ///
    /// <example id="find-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3 |]
    ///
    /// inputs |> Array.find (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>2</c>
    /// </example>
    ///
    /// <example id="find-2">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3 |]
    ///
    /// inputs |> Array.find (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("Find")>]
    val find: predicate: ('T -> bool) -> array: 'T array -> 'T

    /// <summary>Returns the last element for which the given function returns 'true'.
    /// Raise <see cref="T:System.Collections.Generic.KeyNotFoundException"/> if no such element exists.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if <c>predicate</c>
    /// never returns true.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The last element for which <c>predicate</c> returns true.</returns>
    ///
    /// <example id="findback-1">
    /// <code lang="fsharp">
    /// let inputs = [| 2; 3; 4 |]
    ///
    /// inputs |> Array.findBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>4</c>
    /// </example>
    ///
    /// <example id="findback-2">
    /// <code lang="fsharp">
    /// let inputs = [| 2; 3; 4 |]
    ///
    /// inputs |> Array.findBack (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindBack")>]
    val findBack: predicate: ('T -> bool) -> array: 'T array -> 'T

    /// <summary>Returns the index of the first element in the array
    /// that satisfies the given predicate. Raise <see cref="T:System.Collections.Generic.KeyNotFoundException"/> if
    /// none of the elements satisfy the predicate.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if <c>predicate</c>
    /// never returns true.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The index of the first element in the array that satisfies the given predicate.</returns>
    ///
    /// <example id="findindex-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.findIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    ///
    /// <example id="findindex-2">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    /// inputs |> Array.findIndex (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindIndex")>]
    val findIndex: predicate: ('T -> bool) -> array: 'T array -> int

    /// <summary>Returns the index of the last element in the array
    /// that satisfies the given predicate. Raise <see cref="T:System.Collections.Generic.KeyNotFoundException"/> if
    /// none of the elements satisfy the predicate.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.Collections.Generic.KeyNotFoundException">Thrown if <c>predicate</c>
    /// never returns true.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The index of the last element in the array that satisfies the given predicate.</returns>
    ///
    /// <example id="findindexback-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.findIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>3</c>
    /// </example>
    ///
    /// <example id="findindexback-2">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.findIndex (fun elm -> elm % 6 = 0)
    /// </code>
    /// Throws <c>KeyNotFoundException</c>
    /// </example>
    [<CompiledName("FindIndexBack")>]
    val findIndexBack: predicate: ('T -> bool) -> array: 'T array -> int

    /// <summary>Tests if all elements of the array satisfy the given predicate.</summary>
    ///
    /// <remarks>The predicate is applied to the elements of the input collection. If any application
    /// returns false then the overall result is false and no further elements are tested.
    /// Otherwise, true is returned.</remarks>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>True if all of the array elements satisfy the predicate.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="forall-1">
    /// <code lang="fsharp">
    /// let isEven a = a % 2 = 0
    ///
    /// [2; 42] |> Array.forall isEven // evaluates to true
    ///
    /// [1; 2] |> Array.forall isEven // evaluates to false
    /// </code>
    /// </example>
    [<CompiledName("ForAll")>]
    val forall: predicate: ('T -> bool) -> array: 'T array -> bool

    /// <summary>Tests if all corresponding elements of the array satisfy the given predicate pairwise.</summary>
    ///
    /// <remarks>The predicate is applied to matching elements in the two collections up to the lesser of the
    /// two lengths of the collections. If any application returns false then the overall result is
    /// false and no further elements are tested. Otherwise, if one collection is longer
    /// than the other then the <c>ArgumentException</c> exception is raised.
    /// Otherwise, true is returned.</remarks>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>True if all of the array elements satisfy the predicate.</returns>
    ///
    /// <example id="forall2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| 1; 2; 3 |]
    /// let inputs2 = [| 1; 2; 3 |]
    ///
    /// (inputs1, inputs2) ||> Array.forall2 (=)
    /// </code>
    /// Evaluates to <c>true</c>.
    /// </example>
    ///
    /// <example id="forall2-2">
    /// <code lang="fsharp">
    /// let items1 = [| 2017; 1; 1 |]
    /// let items2 = [| 2019; 19; 8 |]
    ///
    /// (items1, items2) ||> Array.forall2 (=)
    /// </code>
    /// Evaluates to <c>false</c>.
    /// </example>
    ///
    /// <example id="forall2-3">
    /// <code lang="fsharp">
    /// let items1 = [| 1; 2; 3 |]
    /// let items2 = [| 1; 2 |]
    ///
    /// (items1, items2) ||> Array.forall2 (=)
    /// </code>
    /// Throws <c>ArgumentException</c>.
    /// </example>
    [<CompiledName("ForAll2")>]
    val forall2: predicate: ('T1 -> 'T2 -> bool) -> array1: 'T1 array -> array2: 'T2 array -> bool

    /// <summary>Applies a function to each element of the collection, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes
    /// <c>f (... (f s i0)...) iN</c></summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The final state.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="fold-1">
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [| In 1; Out 2; In 3 |]
    ///
    /// (0, inputs) ||> Array.fold (fun acc charge ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to <c>2</c>
    /// </example>
    [<CompiledName("Fold")>]
    val fold<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State

    /// <summary>Applies a function to each element of the array, starting from the end, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c> then computes
    /// <c>f i0 (...(f iN s))</c></summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="array">The input array.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <returns>The state object after the folding function is applied to each element of the array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="foldback-1">
    /// <code lang="fsharp">
    /// type Count =
    ///   { Positive: int
    ///     Negative: int
    ///     Text: string }
    ///
    /// let sequence = [| 1; 0; -1; -2; 3 |]
    /// let initialState = {Positive = 0; Negative = 0; Text = "" }
    ///
    /// (sequence, initialState) ||> Array.foldBack (fun a acc  ->
    ///     let text = acc.Text + " " + string a
    ///     if a >= 0 then
    ///         { acc with
    ///             Positive = acc.Positive + 1
    ///             Text = text }
    ///     else
    ///         { acc with
    ///             Negative = acc.Negative + 1
    ///             Text = text })
    /// </code>
    /// Evaluates to
    /// <code>
    /// { Positive = 2
    ///   Negative = 3
    ///   Text = " 3 -2 -1 0 1" }
    /// </code>
    /// </example>
    [<CompiledName("FoldBack")>]
    val foldBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> array: 'T array -> state: 'State -> 'State

    /// <summary>Applies a function to pairs of elements drawn from the two collections,
    /// left-to-right, threading an accumulator argument
    /// through the computation. The two input
    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>The final state.</returns>
    ///
    /// <example id="fold2-1">
    /// <code lang="fsharp">
    /// type CoinToss = Head | Tails
    ///
    /// let data1 = [| Tails; Head; Tails |]
    /// let data2 = [| Tails; Head; Head |]
    ///
    /// (0, data1, data2) |||> Array.fold2 (fun acc a b ->
    ///     match (a, b) with
    ///     | Head, Head -> acc + 1
    ///     | Tails, Tails -> acc + 1
    ///     | _ -> acc - 1)
    /// </code>
    /// Evaluates to <c>1</c>
    /// </example>
    [<CompiledName("Fold2")>]
    val fold2<'T1, 'T2, 'State> :
        folder: ('State -> 'T1 -> 'T2 -> 'State) -> state: 'State -> array1: 'T1 array -> array2: 'T2 array -> 'State

    /// <summary>Apply a function to pairs of elements drawn from the two collections, right-to-left,
    /// threading an accumulator argument through the computation. The two input
    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>The final state.</returns>
    ///
    /// <example id="foldback2-1">
    /// <code lang="fsharp">Count the positives, negatives and accumulate some text from back to front:
    /// type Count =
    ///   { Positive: int
    ///     Negative: int
    ///     Text: string }
    ///
    /// let inputs1 = [| -1; -2; -3 |]
    /// let inputs2 = [| 3; 2; 1 |]
    /// let initialState = {Positive = 0; Negative = 0; Text = ""}
    ///
    /// (inputs1, inputs2, initialState) |||> Array.foldBack2 (fun a b acc  ->
    ///     let text = acc.Text + "(" + string a + "," + string b + ") "
    ///     if a + b >= 0 then
    ///         { acc with
    ///             Positive = acc.Positive + 1
    ///             Text = text }
    ///     else
    ///         { acc with
    ///             Negative = acc.Negative + 1
    ///             Text = text }
    /// )
    /// </code>
    /// Evaluates to
    /// <code>
    /// { Positive = 2
    ///   Negative = 1
    ///   Text = "(-3,1) (-2,2) (-1,3) " }
    /// </code>
    /// </example>
    [<CompiledName("FoldBack2")>]
    val foldBack2<'T1, 'T2, 'State> :
        folder: ('T1 -> 'T2 -> 'State -> 'State) -> array1: 'T1 array -> array2: 'T2 array -> state: 'State -> 'State

    /// <summary>Gets an element from an array.</summary>
    ///
    /// <param name="array">The input array.</param>
    /// <param name="index">The input index.</param>
    ///
    /// <remarks>Normally the syntax <c>array[index]</c> is preferred.</remarks>
    ///
    /// <returns>The value of the array at the given index.</returns>
    ///
    /// <exception cref="T:System.NullReferenceException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.IndexOutOfRangeException">Thrown when the index is negative or the input array does not contain enough elements.</exception>
    ///
    /// <example id="get-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// Array.get inputs 1
    /// </code>
    /// Evaluates to <c>"b"</c>
    /// </example>
    ///
    /// <example id="get-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// Array.get inputs 4
    /// </code>
    /// Throws <c>IndexOutOfRangeException</c>
    /// </example>
    [<CompiledName("Get")>]
    val get: array: 'T array -> index: int -> 'T

    /// <summary>Returns the first element of the array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The first element of the array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <example id="head-1">
    /// <code lang="fsharp">
    /// let inputs = [| "banana"; "pear" |]
    ///
    /// inputs |> Array.head
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="head-2">
    /// <code lang="fsharp">
    /// [| |] |> Array.head
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Head")>]
    val head: array: 'T array -> 'T

    /// <summary>Applies a key-generating function to each element of an array and yields an array of
    /// unique keys. Each unique key contains an array of all elements that match
    /// to this key.</summary>
    ///
    /// <param name="projection">A function that transforms an element of the array into a comparable key.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="group-by-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.groupBy (fun n -> n % 2)
    /// </code>
    /// Evaluates to <c>[| (1, [| 1; 3; 5 |]); (0, [| 2; 4 |]) |]</c>
    /// </example>
    [<CompiledName("GroupBy")>]
    val groupBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * 'T array) array when 'Key: equality

    /// <summary>Builds a new array whose elements are the corresponding elements of the input array
    /// paired with the integer index (from 0) of each element.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array of indexed elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="indexed-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.indexed
    /// </code>
    /// Evaluates to <c>[| (0, "a"); (1, "b"); (2, "c") |]</c>
    /// </example>
    [<CompiledName("Indexed")>]
    val indexed: array: 'T array -> (int * 'T) array

    /// <summary>Creates an array given the dimension and a generator function to compute the elements.</summary>
    ///
    /// <param name="count">The number of elements to initialize.</param>
    /// <param name="initializer">The function to generate the initial values for each index.</param>
    ///
    /// <returns>The created array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when count is negative.</exception>
    ///
    /// <example id="init-1">
    /// <code lang="fsharp">
    /// Array.init 4 (fun v -> v + 5)
    /// </code>
    /// Evaluates to <c>[| 5; 6; 7; 8 |]</c>
    /// </example>
    ///
    /// <example id="init-2">
    /// <code lang="fsharp">
    /// Array.init -5 (fun v -> v + 5)
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Initialize")>]
    val inline init: count: int -> initializer: (int -> 'T) -> 'T array

    /// <summary>Creates an array where the entries are initially the default value Unchecked.defaultof&lt;'T&gt;.</summary>
    ///
    /// <param name="count">The length of the array to create.</param>
    ///
    /// <returns>The created array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when count is negative.</exception>
    ///
    /// <example id="zerocreate-1">
    /// <code lang="fsharp">
    /// let arr : int array = Array.zeroCreate 4
    /// </code>
    /// Evaluates to <c>[| 0; 0; 0; 0 |]</c>
    /// </example>
    [<CompiledName("ZeroCreate")>]
    val zeroCreate: count: int -> 'T array

    /// <summary>Returns true if the given array is empty, otherwise false.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>True if the array is empty.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="empty-1">
    /// <code lang="fsharp">
    /// [| |] |> Array.isEmpty
    /// </code>
    /// Evaluates to <c>true</c>
    /// </example>
    ///
    /// <example id="empty-2">
    /// <code lang="fsharp">
    /// [| "pear"; "banana" |] |> Array.isEmpty
    /// </code>
    /// Evaluates to <c>false</c>
    /// </example>
    [<CompiledName("IsEmpty")>]
    val isEmpty: array: 'T array -> bool

    /// <summary>Applies the given function to each element of the array.</summary>
    ///
    /// <param name="action">The function to apply.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="iter-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.iter (printfn "%s")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// a
    /// b
    /// c
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("Iterate")>]
    val inline iter: action: ('T -> unit) -> array: 'T array -> unit

    /// <summary>Applies the given function to pair of elements drawn from matching indices in two arrays. The
    /// two arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="action">The function to apply.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <example id="iter2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| "a"; "b"; "c" |]
    /// let inputs2 = [| 1; 2; 3 |]
    ///
    /// (inputs1, inputs2) ||> Array.iter2 (printfn "%s: %i")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// a: 1
    /// b: 2
    /// c: 3
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("Iterate2")>]
    val iter2: action: ('T1 -> 'T2 -> unit) -> array1: 'T1 array -> array2: 'T2 array -> unit

    /// <summary>Applies the given function to each element of the array. The integer passed to the
    /// function indicates the index of element.</summary>
    ///
    /// <param name="action">The function to apply to each index and element.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="iteri-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.iteri (fun i v -> printfn "{i}: {v}")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// 0: a
    /// 1: b
    /// 2: c
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("IterateIndexed")>]
    val iteri: action: (int -> 'T -> unit) -> array: 'T array -> unit

    /// <summary>Applies the given function to pair of elements drawn from matching indices in two arrays,
    /// also passing the index of the elements. The two arrays must have the same lengths,
    /// otherwise an <c>ArgumentException</c> is raised.</summary>
    ///
    /// <param name="action">The function to apply to each index and pair of elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <example id="iteri2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| "a"; "b"; "c" |]
    /// let inputs2 = [| "banana"; "pear"; "apple" |]
    ///
    /// (inputs1, inputs2) ||> Array.iteri2 (fun i s1 s2 -> printfn "Index {i}: {s1} - {s2}")
    /// </code>
    /// Evaluates to <c>unit</c> and prints
    /// <code>
    /// Index 0: a - banana
    /// Index 1: b - pear
    /// Index 2: c - apple
    /// </code>
    /// in the console.
    /// </example>
    [<CompiledName("IterateIndexed2")>]
    val iteri2: action: (int -> 'T1 -> 'T2 -> unit) -> array1: 'T1 array -> array2: 'T2 array -> unit

    /// <summary>Returns the last element of the array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The last element of the array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input does not have any elements.</exception>
    ///
    /// <example id="last-1">
    /// <code lang="fsharp">
    /// [| "pear"; "banana" |] |> Array.last
    /// </code>
    /// Evaluates to <c>banana</c>
    /// </example>
    ///
    /// <example id="last-2">
    /// <code lang="fsharp">
    /// [| |] |> Array.last
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Last")>]
    val inline last: array: 'T array -> 'T

    /// <summary>Gets an element from an array.</summary>
    ///
    /// <param name="index">The input index.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The value of the array at the given index.</returns>
    ///
    /// <remarks>Normally the syntax <c>array[index]</c> is preferred.</remarks>
    ///
    /// <exception cref="T:System.NullReferenceException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.IndexOutOfRangeException">Thrown when the index is negative or the input array does not contain enough elements.</exception>
    ///
    /// <example id="item-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.item 1
    /// </code>
    /// Evaluates to <c>"b"</c>
    /// </example>
    ///
    /// <example id="item-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.item 4
    /// </code>
    /// Throws <c>ArgumentException</c>
    /// </example>
    [<CompiledName("Item")>]
    val item: index: int -> array: 'T array -> 'T

    /// <summary>Returns the length of an array. You can also use property arr.Length.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The length of the array.</returns>
    ///
    /// <remarks>The notation <c>array.Length</c> is preferred.</remarks>
    ///
    /// <exception cref="T:System.NullReferenceException">Thrown when the input array is null.</exception>
    ///
    /// <example id="length-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.length
    /// </code>
    /// Evaluates to <c>3</c>
    /// </example>
    [<CompiledName("Length")>]
    val length: array: 'T array -> int

    /// <summary>Returns the last element of the array.
    /// Return <c>None</c> if no such element exists.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The last element of the array or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="trylast-1">
    /// <code lang="fsharp">
    /// [| "pear"; "banana" |] |> Array.tryLast
    /// </code>
    /// Evaluates to <c>Some "banana"</c>
    /// </example>
    ///
    /// <example id="trylast-2">
    /// <code lang="fsharp">
    /// [| |] |> Array.tryLast
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryLast")>]
    val tryLast: array: 'T array -> 'T option

    /// <summary>Builds a new array whose elements are the results of applying the given function
    /// to each of the elements of the array.</summary>
    ///
    /// <param name="mapping">The function to transform elements of the array.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array of transformed elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="map-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "bbb"; "cc" |]
    ///
    /// inputs |> Array.map (fun x -> x.Length)
    /// </code>
    /// Evaluates to <c>[| 1; 3; 2 |]</c>
    /// </example>
    [<CompiledName("Map")>]
    val inline map: mapping: ('T -> 'U) -> array: 'T array -> 'U array

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding elements of the two collections pairwise. The two input
    /// arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="mapping">The function to transform the pairs of the input elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    ///
    /// <returns>The array of transformed elements.</returns>
    ///
    /// <example id="map2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| "a"; "bad"; "good" |]
    /// let inputs2 = [| 0; 2; 1 |]
    ///
    /// (inputs1, inputs2) ||> Array.map2 (fun x y -> x[y])
    /// </code>
    /// Evaluates to <c>[| 'a'; 'd'; 'o' |]</c>
    /// </example>
    [<CompiledName("Map2")>]
    val map2: mapping: ('T1 -> 'T2 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> 'U array

    /// <summary>Combines map and fold. Builds a new array whose elements are the results of applying the given function
    /// to each of the elements of the input array. The function is also used to accumulate a final value.</summary>
    ///
    /// <param name="mapping">The function to transform elements from the input array and accumulate the final value.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The array of transformed elements, and the final accumulated value.</returns>
    ///
    /// <example id="mapfold-1">
    /// <code lang="fsharp">Accumulate the charges, and double them as well
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [| In 1; Out 2; In 3 |]
    ///
    /// let newCharges, balance =
    ///     (0, inputs) ||> Array.mapFold (fun acc charge ->
    ///         match charge with
    ///         | In i -> In (i*2), acc + i
    ///         | Out o -> Out (o*2), acc - o)
    /// </code>
    /// Evaluates <c>newCharges</c> to <c>[|In 2; Out 4; In 6|]</c> and <c>balance</c> to <c>2</c>.
    /// </example>
    [<CompiledName("MapFold")>]
    val mapFold<'T, 'State, 'Result> :
        mapping: ('State -> 'T -> 'Result * 'State) -> state: 'State -> array: 'T array -> 'Result array * 'State

    /// <summary>Combines map and foldBack. Builds a new array whose elements are the results of applying the given function
    /// to each of the elements of the input array. The function is also used to accumulate a final value.</summary>
    ///
    /// <param name="mapping">The function to transform elements from the input array and accumulate the final value.</param>
    /// <param name="array">The input array.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The array of transformed elements, and the final accumulated value.</returns>
    ///
    /// <example id="mapfold-1">Accumulate the charges from back to front, and double them as well
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [| In 1; Out 2; In 3 |]
    ///
    /// let newCharges, balance =
    ///     (inputs, 0) ||> Array.mapFoldBack (fun charge acc ->
    ///         match charge with
    ///         | In i -> In (i*2), acc + i
    ///         | Out o -> Out (o*2), acc - o)
    /// </code>
    /// Evaluates <c>newCharges</c> to <c>[|In 2; Out 4; In 6|]</c> and <c>balance</c> to <c>2</c>.
    /// </example>
    [<CompiledName("MapFoldBack")>]
    val mapFoldBack<'T, 'State, 'Result> :
        mapping: ('T -> 'State -> 'Result * 'State) -> array: 'T array -> state: 'State -> 'Result array * 'State

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding triples from the three collections. The three input
    /// arrays must have the same length, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="mapping">The function to transform the pairs of the input elements.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    /// <param name="array3">The third input array.</param>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when any of the input arrays is null.</exception>
    ///
    /// <returns>The array of transformed elements.</returns>
    ///
    /// <example id="map3-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| "a"; "t"; "ti" |]
    /// let inputs2 = [| "l"; "h"; "m" |]
    /// let inputs3 = [| "l"; "e"; "e" |]
    ///
    /// (inputs1, inputs2, inputs3) |||> Array.map3 (fun x y z -> x + y + z)
    /// </code>
    /// Evaluates to <c>[| "all"; "the"; "time" |]</c>
    /// </example>
    ///
    [<CompiledName("Map3")>]
    val map3:
        mapping: ('T1 -> 'T2 -> 'T3 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> array3: 'T3 array -> 'U array

    /// <summary>Builds a new collection whose elements are the results of applying the given function
    /// to the corresponding elements of the two collections pairwise, also passing the index of
    /// the elements. The two input arrays must have the same lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="mapping">The function to transform pairs of input elements and their indices.</param>
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>The array of transformed elements.</returns>
    ///
    /// <example id="mapi2-1">
    /// <code lang="fsharp">
    /// let inputs1 = [| "a"; "bad"; "good" |]
    /// let inputs2 = [| 0; 2; 1 |]
    ///
    /// (inputs1, inputs2) ||> Array.mapi2 (fun i x y -> i, x[y])
    /// </code>
    /// Evaluates to <c>[|(0, 'a'); (1, 'd'); (2, 'o')|]</c>
    /// </example>
    [<CompiledName("MapIndexed2")>]
    val mapi2: mapping: (int -> 'T1 -> 'T2 -> 'U) -> array1: 'T1 array -> array2: 'T2 array -> 'U array

    /// <summary>Builds a new array whose elements are the results of applying the given function
    /// to each of the elements of the array. The integer index passed to the
    /// function indicates the index of element being transformed, starting at zero.</summary>
    ///
    /// <param name="mapping">The function to transform elements and their indices.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array of transformed elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="mapi-1">
    /// <code lang="fsharp">
    /// let inputs = [| 10; 10; 10 |]
    ///
    /// inputs |> Array.mapi (fun i x -> i + x)
    /// </code>
    /// Evaluates to <c>[| 10; 11; 12 |]</c>
    /// </example>
    [<CompiledName("MapIndexed")>]
    val mapi: mapping: (int -> 'T -> 'U) -> array: 'T array -> 'U array

    /// <summary>Returns the greatest of all elements of the array, compared via Operators.max on the function result.</summary>
    ///
    /// <remarks>Throws ArgumentException for empty arrays.</remarks>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The maximum element.</returns>
    ///
    /// <example id="max-1">
    /// <code lang="fsharp">
    /// let inputs = [| 10; 12; 11 |]
    ///
    /// inputs |> Array.max
    /// </code>
    /// Evaluates to <c>12</c>
    /// </example>
    ///
    /// <example id="max-2">
    /// <code lang="fsharp">
    /// let inputs: int array= [| |]
    ///
    /// inputs |> Array.max
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("Max")>]
    val inline max: array: 'T array -> 'T when 'T: comparison

    /// <summary>Returns the greatest of all elements of the array, compared via Operators.max on the function result.</summary>
    ///
    /// <remarks>Throws ArgumentException for empty arrays.</remarks>
    ///
    /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The maximum element.</returns>
    ///
    /// <example id="maxby-1">
    /// <code lang="fsharp">
    /// let inputs = [| "aaa"; "b"; "cccc" |]
    ///
    /// inputs |> Array.maxBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>"cccc"</c>
    /// </example>
    ///
    /// <example id="maxby-2">
    /// <code lang="fsharp">
    /// let inputs: string array= [| |]
    ///
    /// inputs |> Array.maxBy (fun s -> s.Length)
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("MaxBy")>]
    val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison

    /// <summary>Returns the lowest of all elements of the array, compared via Operators.min.</summary>
    ///
    /// <remarks>Throws ArgumentException for empty arrays</remarks>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The minimum element.</returns>
    ///
    /// <example id="min-1">
    /// <code lang="fsharp">
    /// let inputs = [| 10; 12; 11 |]
    ///
    /// inputs |> Array.min
    /// </code>
    /// Evaluates to <c>10</c>
    /// </example>
    ///
    /// <example id="min-2">
    /// <code lang="fsharp">
    /// let inputs: int array= [| |]
    ///
    /// inputs |> Array.min
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("Min")>]
    val inline min: array: 'T array -> 'T when 'T: comparison

    /// <summary>Returns the lowest of all elements of the array, compared via Operators.min on the function result.</summary>
    ///
    /// <remarks>Throws ArgumentException for empty arrays.</remarks>
    ///
    /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The minimum element.</returns>
    ///
    /// <example id="minby-1">
    /// <code lang="fsharp">
    /// let inputs = [| "aaa"; "b"; "cccc" |]
    ///
    /// inputs |> Array.minBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>"b"</c>
    /// </example>
    ///
    /// <example id="minby-2">
    /// <code lang="fsharp">
    /// let inputs: string array= [| |]
    ///
    /// inputs |> Array.minBy (fun s -> s.Length)
    /// </code>
    /// Throws <c>System.ArgumentException</c>.
    /// </example>
    [<CompiledName("MinBy")>]
    val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison

    /// <summary>Builds an array from the given list.</summary>
    ///
    /// <param name="list">The input list.</param>
    ///
    /// <returns>The array of elements from the list.</returns>
    ///
    /// <example id="oflist-1">
    /// <code lang="fsharp">
    /// let inputs = [ 1; 2; 5 ]
    ///
    /// inputs |> Array.ofList
    /// </code>
    /// Evaluates to <c>[| 1; 2; 5 |]</c>.
    /// </example>
    [<CompiledName("OfList")>]
    val ofList: list: 'T list -> 'T array

    /// <summary>Builds a new array from the given enumerable object.</summary>
    ///
    /// <param name="source">The input sequence.</param>
    ///
    /// <returns>The array of elements from the sequence.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="ofseq-1">
    /// <code lang="fsharp">
    /// let inputs = seq { 1; 2; 5 }
    ///
    /// inputs |> Array.ofSeq
    /// </code>
    /// Evaluates to <c>[| 1; 2; 5 |]</c>.
    /// </example>
    [<CompiledName("OfSeq")>]
    val ofSeq: source: seq<'T> -> 'T array

    /// <summary>Returns an array of each element in the input array paired with its predecessor, with the
    /// exception of the first element which is only returned as the predecessor of the second element.
    /// The predecessor comes first in the returned pairs.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    ///
    /// <example id="pairwise-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.pairwise
    /// </code>
    /// Evaluates to <c>[|(1, 2); (2, 3); (3, 4)|]</c>.
    /// </example>
    [<CompiledName("Pairwise")>]
    val pairwise: array: 'T array -> ('T * 'T) array

    /// <summary>Splits the collection into two collections, containing the
    /// elements for which the given predicate returns "true" and "false"
    /// respectively.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>A pair of arrays. The first containing the elements the predicate evaluated to true,
    /// and the second containing those evaluated to false.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="partition-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.partition (fun x -> x % 2 = 0)
    /// </code>
    /// Evaluates to <c>([|2; 4|], [|1; 3|])</c>.
    /// </example>
    [<CompiledName("Partition")>]
    val partition: predicate: ('T -> bool) -> array: 'T array -> 'T array * 'T array

    /// <summary>Returns an array with all elements permuted according to the
    /// specified permutation.</summary>
    ///
    /// <param name="indexMap">The function that maps input indices to output indices.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The output array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when indexMap does not produce a valid permutation.</exception>
    ///
    /// <example id="permute-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.permute (fun x -> (x + 1) % 4)
    /// </code>
    /// Evaluates to <c>[|4; 1; 2; 3|]</c>.
    /// </example>
    [<CompiledName("Permute")>]
    val permute: indexMap: (int -> int) -> array: 'T array -> 'T array

    /// <summary>Applies a function to each element of the array, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c>
    /// then computes <c>f (... (f i0 i1)...) iN</c>.
    /// Raises ArgumentException if the array has size zero.</summary>
    ///
    /// <param name="reduction">The function to reduce a pair of elements to a single element.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The final result of the reductions.</returns>
    ///
    /// <example id="reduce-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 3; 4; 2 |]
    ///
    /// inputs |> Array.reduce (fun a b -> a * 10 + b)
    /// </code>
    /// Evaluates to <c>1342</c>, by computing <c>((1 * 10 + 3) * 10 + 4) * 10 + 2</c>
    /// </example>
    [<CompiledName("Reduce")>]
    val reduce: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T

    /// <summary>Applies a function to each element of the array, starting from the end, threading an accumulator argument
    /// through the computation. If the input function is <c>f</c> and the elements are <c>i0...iN</c>
    /// then computes <c>f i0 (...(f iN-1 iN))</c>.</summary>
    ///
    /// <param name="reduction">A function that takes in the next-to-last element of the list and the
    /// current accumulated result to produce the next accumulated result.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <returns>The final result of the reductions.</returns>
    ///
    /// <example id="reduceback-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 3; 4; 2 |]
    ///
    /// inputs |> Array.reduceBack (fun a b -> a + b * 10)
    /// </code>
    /// Evaluates to <c>2431</c>, by computing <c>1 + (3 + (4 + 2 * 10) * 10) * 10</c>
    /// </example>
    [<CompiledName("ReduceBack")>]
    val reduceBack: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T

    /// <summary>Creates an array by replicating the given initial value.</summary>
    ///
    /// <param name="count">The number of elements to replicate.</param>
    /// <param name="initial">The value to replicate</param>
    ///
    /// <returns>The generated array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when count is negative.</exception>
    ///
    /// <example id="replicate-1">
    /// <code lang="fsharp">
    /// Array.replicate 3 "a"
    /// </code>
    /// Evaluates to <c>[| "a"; "a"; "a" |]</c>.
    /// </example>
    [<CompiledName("Replicate")>]
    val replicate: count: int -> initial: 'T -> 'T array

    /// <summary>Returns a new array with the elements in reverse order.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The reversed array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="rev-1">
    /// <code lang="fsharp">
    /// Array.rev [| 0; 1; 2 |]
    /// </code>
    /// Evaluates to <c>[| 2; 1; 0 |]</c>.
    /// </example>
    [<CompiledName("Reverse")>]
    val rev: array: 'T array -> 'T array

    /// <summary>Like <c>fold</c>, but return the intermediary and final results.</summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="state">The initial state.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The array of state values.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="scan-1">Apply a list charges and collect the running balances as each is applied:
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [| In 1; Out 2; In 3 |]
    ///
    /// (0, inputs) ||> Array.scan (fun acc charge ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to <c>[|0; 1; -1; 2|]</c>. Note <c>0</c> is the initial
    /// state, <c>1</c> the next state, <c>-1</c> the next state, and <c>2</c> the final state.
    /// </example>
    [<CompiledName("Scan")>]
    val scan<'T, 'State> : folder: ('State -> 'T -> 'State) -> state: 'State -> array: 'T array -> 'State array

    /// <summary>Like <c>foldBack</c>, but return both the intermediary and final results.</summary>
    ///
    /// <param name="folder">The function to update the state given the input elements.</param>
    /// <param name="array">The input array.</param>
    /// <param name="state">The initial state.</param>
    ///
    /// <returns>The array of state values.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="scan-1">Apply a list charges from back to front, and collect the running balances as each is applied:
    /// <code lang="fsharp">
    /// type Charge =
    ///     | In of int
    ///     | Out of int
    ///
    /// let inputs = [| In 1; Out 2; In 3 |]
    ///
    /// (inputs, 0) ||> Array.scanBack (fun charge acc ->
    ///     match charge with
    ///     | In i -> acc + i
    ///     | Out o -> acc - o)
    /// </code>
    /// Evaluates to <c> [|2; 1; 3; 0|]</c> by processing each input from back to front. Note <c>0</c> is the initial
    /// state, <c>3</c> the next state, <c>1</c> the next state, and <c>2</c> the final state.
    /// </example>
    [<CompiledName("ScanBack")>]
    val scanBack<'T, 'State> : folder: ('T -> 'State -> 'State) -> array: 'T array -> state: 'State -> 'State array

    /// <summary>Returns an array that contains one item only.</summary>
    ///
    /// <param name="value">The input item.</param>
    ///
    /// <returns>The result array of one item.</returns>
    ///
    /// <example id="singleton-1">
    /// <code lang="fsharp">
    /// Array.singleton 7
    /// </code>
    /// Evaluates to <c>[| 7 |]</c>.
    /// </example>
    [<CompiledName("Singleton")>]
    val inline singleton: value: 'T -> 'T array

    /// <summary>Sets an element of an array.</summary>
    ///
    /// <param name="array">The input array.</param>
    /// <param name="index">The input index.</param>
    /// <param name="value">The input value.</param>
    ///
    /// <exception cref="T:System.NullReferenceException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.IndexOutOfRangeException">Thrown when the index is negative or the input array does not contain enough elements.</exception>
    ///
    /// <example id="set-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// Array.set inputs 1 "B"
    /// </code>
    /// After evaluation <c>inputs</c> contains <c>[| "a"; "B"; "c" |]</c>
    /// </example>
    ///
    /// <example id="set-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// Array.set inputs 4 "d"
    /// </code>
    /// Throws <c>IndexOutOfRangeException</c>
    /// </example>
    [<CompiledName("Set")>]
    val set: array: 'T array -> index: int -> value: 'T -> unit

    /// <summary>Builds a new array that contains the elements of the given array, excluding the first N elements.</summary>
    ///
    /// <param name="count">The number of elements to skip. If negative the full array will be returned as a copy.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>A copy of the input array, after removing the first N elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count exceeds the number of
    /// elements in the array.</exception>
    ///
    /// <example id="skip-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.skip 2
    /// </code>
    /// Evaluates to <c>[| "c"; "d" |]</c>
    /// </example>
    ///
    /// <example id="skip-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.skip 5
    /// </code>
    /// Throws <c>ArgumentException</c>.
    /// </example>
    ///
    /// <example id="skip-3">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.skip -1
    /// </code>
    /// Evaluates to <c>[| "a"; "b"; "c"; "d" |]</c>.
    /// </example>
    [<CompiledName("Skip")>]
    val skip: count: int -> array: 'T array -> 'T array

    /// <summary>Bypasses elements in an array while the given predicate returns True, and then returns
    /// the remaining elements in a new array.</summary>
    ///
    /// <param name="predicate">A function that evaluates an element of the array to a boolean value.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The created sub array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="skipwhile-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "bbb"; "cc"; "d" |]
    ///
    /// inputs |> Array.skipWhile (fun x -> x.Length &lt; 3)
    /// </code>
    /// Evaluates to <c>[|"bbb"; "cc"; "d"|]</c>
    /// </example>
    ///
    [<CompiledName("SkipWhile")>]
    val skipWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array

    /// <summary>Builds a new array that contains the given subrange specified by
    /// starting index and length.</summary>
    ///
    /// <param name="array">The input array.</param>
    /// <param name="startIndex">The index of the first element of the sub array.</param>
    /// <param name="count">The length of the sub array.</param>
    ///
    /// <returns>The created sub array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when either startIndex or count is negative,
    /// or when there aren't enough elements in the input array.</exception>
    ///
    /// <remarks>
    /// Slicing syntax is generally preferred, e.g.
    /// <code lang="fsharp">
    /// let input = [| 0; 1; 2; 3; 4; 5 |]
    ///
    /// input.[2..4]
    /// </code>
    /// </remarks>
    ///
    /// <example id="sub-1">
    /// <code lang="fsharp">
    /// let input = [| 0; 1; 2; 3; 4; 5 |]
    ///
    /// Array.sub input 2 3
    /// </code>
    /// Evaluates to <c>[| 2; 3; 4 |]</c>.
    /// </example>
    [<CompiledName("GetSubArray")>]
    val sub: array: 'T array -> startIndex: int -> count: int -> 'T array

    /// <summary>Sorts the elements of an array, returning a new array. Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>. </summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sorted array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sort-1">
    /// <code lang="fsharp">
    /// let input = [| 8; 4; 3; 1; 6; 1 |]
    ///
    /// Array.sort input
    /// </code>
    /// Evaluates to <c>[| 1; 1; 3; 4; 6; 8 |]</c>.
    /// </example>
    [<CompiledName("Sort")>]
    val sort: array: 'T array -> 'T array when 'T: comparison

    /// <summary>Sorts the elements of an array, using the given projection for the keys and returning a new array.
    /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="projection">The function to transform array elements into the type that is compared.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sorted array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sortby-1">
    /// <code lang="fsharp">
    /// let input = [| "a"; "bbb"; "cccc"; "dd" |]
    ///
    /// input |> Array.sortBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>[|"a"; "dd"; "bbb"; "cccc"|]</c>.
    /// </example>
    [<CompiledName("SortBy")>]
    val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison

    /// <summary>Sorts the elements of an array, using the given comparison function as the order, returning a new array.</summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="comparer">The function to compare pairs of array elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sorted array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sortwith-1">Sort an array of pairs using a comparison function that compares string lengths then index numbers:
    /// <code lang="fsharp">
    /// let compareEntries (n1: int, s1: string) (n2: int, s2: string) =
    ///     let c = compare s1.Length s2.Length
    ///     if c &lt;> 0 then c else
    ///     compare n1 n2
    ///
    /// let input = [| (0,"aa"); (1,"bbb"); (2,"cc"); (3,"dd") |]
    ///
    /// input |> Array.sortWith compareEntries
    /// </code>
    /// Evaluates to <c>[|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]</c>.
    /// </example>
    [<CompiledName("SortWith")>]
    val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array

    /// <summary>Sorts the elements of an array by mutating the array in-place, using the given projection for the keys.
    /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="projection">The function to transform array elements into the type that is compared.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sortinplaceby-1">
    /// <code lang="fsharp">
    /// let array = [| "a"; "bbb"; "cccc"; "dd" |]
    ///
    /// array |> Array.sortInPlaceBy (fun s -> s.Length)
    /// </code>
    /// After evaluation <c>array</c> contains <c>[|"a"; "dd"; "bbb"; "cccc"|]</c>.
    /// </example>
    [<CompiledName("SortInPlaceBy")>]
    val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison

    /// <summary>Sorts the elements of an array by mutating the array in-place, using the given comparison function as the order.</summary>
    ///
    /// <param name="comparer">The function to compare pairs of array elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sortinplacewith-1"> The following sorts entries using a comparison function that compares string lengths then index numbers:
    /// <code lang="fsharp">
    /// let compareEntries (n1: int, s1: string) (n2: int, s2: string) =
    ///     let c = compare s1.Length s2.Length
    ///     if c &lt;> 0 then c else
    ///     compare n1 n2
    ///
    /// let array = [| (0,"aa"); (1,"bbb"); (2,"cc"); (3,"dd") |]
    ///
    /// array |> Array.sortInPlaceWith compareEntries
    /// </code>
    /// After evaluation <c>array</c> contains <c>[|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]</c>.
    /// </example>
    [<CompiledName("SortInPlaceWith")>]
    val sortInPlaceWith: comparer: ('T -> 'T -> int) -> array: 'T array -> unit

    /// <summary>Sorts the elements of an array by mutating the array in-place, using the given comparison function.
    /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sortinplace-1">
    /// <code lang="fsharp">
    /// let array = [| 8; 4; 3; 1; 6; 1 |]
    ///
    /// Array.sortInPlace array
    /// </code>
    /// After evaluation <c>array</c> contains <c>[| 1; 1; 3; 4; 6; 8 |]</c>.
    /// </example>
    [<CompiledName("SortInPlace")>]
    val sortInPlace: array: 'T array -> unit when 'T: comparison

    /// <summary>Splits an array into two arrays, at the given index.</summary>
    ///
    /// <param name="index">The index at which the array is split.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The two split arrays.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.InvalidOperationException">Thrown when split index exceeds the number of elements
    /// in the array.</exception>
    ///
    /// <example id="splitat-1">
    /// <code lang="fsharp">
    /// let input = [| 8; 4; 3; 1; 6; 1 |]
    ///
    /// let front, back = input |> Array.splitAt 3
    /// </code>
    /// Evaluates <c>front</c> to <c>[|8; 4; 3|]</c> and <c>back</c> to <c>[|1; 6; 1|]</c>.
    /// </example>
    [<CompiledName("SplitAt")>]
    val splitAt: index: int -> array: 'T array -> ('T array * 'T array)

    /// <summary>Sorts the elements of an array, in descending order, returning a new array. Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>. </summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sorted array.</returns>
    ///
    /// <example id="sortdescending-1">
    /// <code lang="fsharp">
    /// let input = [| 8; 4; 3; 1; 6; 1 |]
    ///
    /// input |> Array.sortDescending
    /// </code>
    /// Evaluates to <c>[| 8; 6; 4; 3; 1; 1 |]</c>.
    /// </example>
    [<CompiledName("SortDescending")>]
    val inline sortDescending: array: 'T array -> 'T array when 'T: comparison

    /// <summary>Sorts the elements of an array, in descending order, using the given projection for the keys and returning a new array.
    /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
    ///
    /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
    /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
    ///
    /// <param name="projection">The function to transform array elements into the type that is compared.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sorted array.</returns>
    ///
    /// <example id="sortbydescending-1">
    /// <code lang="fsharp">
    /// let input = [| "a"; "bbb"; "cccc"; "dd" |]
    ///
    /// input |> Array.sortByDescending (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>[|"cccc"; "bbb"; "dd"; "a"|]</c>.
    /// </example>
    [<CompiledName("SortByDescending")>]
    val inline sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison

    /// <summary>Returns the sum of the elements in the array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The resulting sum.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sum-1">
    /// <code lang="fsharp">
    /// let input = [| 1; 5; 3; 2 |]
    ///
    /// input |> Array.sum
    /// </code>
    /// Evaluates to <c>11</c>.
    /// </example>
    [<CompiledName("Sum")>]
    val inline sum: array: ^T array -> ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T)

    /// <summary>Returns the sum of the results generated by applying the function to each element of the array.</summary>
    ///
    /// <param name="projection">The function to transform the array elements into the type to be summed.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The resulting sum.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="sumby-1">
    /// <code lang="fsharp">
    /// let input = [| "aa"; "bbb"; "cc" |]
    ///
    /// input |> Array.sumBy (fun s -> s.Length)
    /// </code>
    /// Evaluates to <c>7</c>.
    /// </example>
    [<CompiledName("SumBy")>]
    val inline sumBy:
        projection: ('T -> ^U) -> array: 'T array -> ^U
            when ^U: (static member (+): ^U * ^U -> ^U) and ^U: (static member Zero: ^U)

    /// <summary>Returns the first N elements of the array.</summary>
    /// <remarks>Throws <c>InvalidOperationException</c>
    /// if the count exceeds the number of elements in the array. <c>Array.truncate</c>
    /// returns as many items as the array contains instead of throwing an exception.</remarks>
    ///
    /// <param name="count">The number of items to take.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    /// <exception cref="T:System.InvalidOperationException">Thrown when count exceeds the number of elements
    /// in the list.</exception>
    ///
    /// <example id="take-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.take 2
    /// </code>
    /// Evaluates to <c>[| "a"; "b" |]</c>
    /// </example>
    ///
    /// <example id="take-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.take 6
    /// </code>
    /// Throws <c>InvalidOperationException</c>.
    /// </example>
    ///
    /// <example id="take-3">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.take 0
    /// </code>
    /// Evaluates to <c>[| |]</c>.
    /// </example>
    [<CompiledName("Take")>]
    val take: count: int -> array: 'T array -> 'T array

    /// <summary>Returns an array that contains all elements of the original array while the
    /// given predicate returns True, and then returns no further elements.</summary>
    ///
    /// <param name="predicate">A function that evaluates to false when no more items should be returned.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="takewhile-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "bb"; "ccc"; "d" |]
    ///
    /// inputs |> Array.takeWhile (fun x -> x.Length &lt; 3)
    /// </code>
    /// Evaluates to <c>[| "a"; "bb" |]</c>
    /// </example>
    ///
    [<CompiledName("TakeWhile")>]
    val takeWhile: predicate: ('T -> bool) -> array: 'T array -> 'T array

    /// <summary>Returns a new array containing the elements of the original except the first element.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when the array is empty.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>A new array containing the elements of the original except the first element.</returns>
    ///
    /// <example id="tail-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "bb"; "ccc" |]
    ///
    /// inputs |> Array.tail
    /// </code>
    /// Evaluates to <c>[| "bb"; "ccc" |]</c>
    /// </example>
    ///
    [<CompiledName("Tail")>]
    val tail: array: 'T array -> 'T array

    /// <summary>Builds a list from the given array.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The list of array elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="tolist-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 5 |]
    ///
    /// inputs |> Array.toList
    /// </code>
    /// Evaluates to <c>[ 1; 2; 5 ]</c>.
    /// </example>
    [<CompiledName("ToList")>]
    val toList: array: 'T array -> 'T list

    /// <summary>Views the given array as a sequence.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The sequence of array elements.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="toseq-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 5 |]
    ///
    /// inputs |> Array.toSeq
    /// </code>
    /// Evaluates to <c>seq { 1; 2; 5 }</c>.
    /// </example>
    [<CompiledName("ToSeq")>]
    val toSeq: array: 'T array -> seq<'T>

    /// <summary>Returns the transpose of the given sequence of arrays.</summary>
    ///
    /// <param name="arrays">The input sequence of arrays.</param>
    ///
    /// <returns>The transposed array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input sequence is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <example id="transpose-1">
    /// <code lang="fsharp">
    /// let inputs =
    ///     [| [| 10; 20; 30 |]
    ///        [| 11; 21; 31 |] |]
    ///
    /// inputs |> Array.transpose
    /// </code>
    /// Evaluates to <c>[|[|10; 11|]; [|20; 21|]; [|30; 31|]|]</c>.
    /// </example>
    [<CompiledName("Transpose")>]
    val transpose: arrays: seq<'T array> -> 'T array array

    /// <summary>Returns at most N elements in a new array.</summary>
    ///
    /// <param name="count">The maximum number of items to return.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="truncate-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.truncate 2
    /// </code>
    /// Evaluates to <c>[| "a"; "b" |]</c>
    /// </example>
    ///
    /// <example id="truncate-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.truncate 6
    /// </code>
    /// Evaluates to <c>[| "a"; "b"; "c"; "d" |]</c>
    /// </example>
    ///
    /// <example id="truncate-3">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c"; "d" |]
    ///
    /// inputs |> Array.truncate 0
    /// </code>
    /// Evaluates to <c>[| |]</c>.
    /// </example>
    [<CompiledName("Truncate")>]
    val truncate: count: int -> array: 'T array -> 'T array

    /// <summary>Returns the first element for which the given function returns True.
    /// Return None if no such element exists.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The first element that satisfies the predicate, or None.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="tryfind-1">Try to find the first even number:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3 |]
    ///
    /// inputs |> Array.tryFind (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 2</c>
    /// </example>
    ///
    /// <example id="tryfind-2">Try to find the first even number:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 5; 3 |]
    ///
    /// inputs |> Array.tryFind (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFind")>]
    val tryFind: predicate: ('T -> bool) -> array: 'T array -> 'T option

    /// <summary>Returns the last element for which the given function returns True.
    /// Return None if no such element exists.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The last element that satisfies the predicate, or None.</returns>
    ///
    /// <example id="tryfindback-1">Try to find the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.tryFindBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 4</c>
    /// </example>
    ///
    /// <example id="tryfindback-2">Try to find the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 5; 3 |]
    ///
    /// inputs |> Array.tryFindBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindBack")>]
    val tryFindBack: predicate: ('T -> bool) -> array: 'T array -> 'T option

    /// <summary>Returns the index of the first element in the array
    /// that satisfies the given predicate.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The index of the first element that satisfies the predicate, or None.</returns>
    ///
    /// <example id="tryfindindex-1">Try to find the index of the first even number:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.tryFindIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 1</c>
    /// </example>
    ///
    /// <example id="tryfindindex-2">Try to find the index of the first even number:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 3; 5; 7 |]
    ///
    /// inputs |> Array.tryFindIndex (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindIndex")>]
    val tryFindIndex: predicate: ('T -> bool) -> array: 'T array -> int option

    /// <summary>Tries to find the nth element in the array.
    /// Returns <c>None</c> if index is negative or the input array does not contain enough elements.</summary>
    ///
    /// <param name="index">The index of element to retrieve.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The nth element of the array or <c>None</c>.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="tryitem-1">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.tryItem 1
    /// </code>
    /// Evaluates to <c>Some "b"</c>.
    /// </example>
    ///
    /// <example id="tryitem-2">
    /// <code lang="fsharp">
    /// let inputs = [| "a"; "b"; "c" |]
    ///
    /// inputs |> Array.tryItem 4
    /// </code>
    /// Evaluates to <c>None</c>.
    /// </example>
    [<CompiledName("TryItem")>]
    val tryItem: index: int -> array: 'T array -> 'T option

    /// <summary>Returns the index of the last element in the array
    /// that satisfies the given predicate.</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <returns>The index of the last element that satisfies the predicate, or None.</returns>
    ///
    /// <example id="tryfindindexback-1">Try to find the index of the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.tryFindIndexBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>Some 3</c>
    /// </example>
    ///
    /// <example id="tryfindindexback-2">Try to find the index of the first even number from the back:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 3; 5; 7 |]
    ///
    /// inputs |> Array.tryFindIndexBack (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>None</c>
    /// </example>
    [<CompiledName("TryFindIndexBack")>]
    val tryFindIndexBack: predicate: ('T -> bool) -> array: 'T array -> int option

    /// <summary>Returns an array that contains the elements generated by the given computation.
    /// The generator is repeatedly called to build the list until it returns `None`.
    /// The given initial <c>state</c> argument is passed to the element generator.</summary>
    ///
    /// <param name="generator">A function that takes in the current state and returns an option tuple of the next
    /// element of the array and the next state value.</param>
    /// <param name="state">The initial state value.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <example id="unfold-1">
    /// <code lang="fsharp">
    /// 1 |> Array.unfold (fun state -> if state > 100 then None else Some (state, state * 2))
    /// </code>
    /// Evaluates to <c>[| 1; 2; 4; 8; 16; 32; 64 |]</c>
    /// </example>
    [<CompiledName("Unfold")>]
    val unfold<'T, 'State> : generator: ('State -> ('T * 'State) option) -> state: 'State -> 'T array

    /// <summary>Splits an array of pairs into two arrays.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The two arrays.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="unzip-1">
    /// <code lang="fsharp">
    /// let inputs = [| (1, "one"); (2, "two") |]
    ///
    /// let numbers, names = inputs |> Array.unzip
    /// </code>
    /// Evaluates <c>numbers</c> to <c>[|1; 2|]</c> and <c>names</c> to <c>[|"one"; "two"|]</c>.
    /// </example>
    [<CompiledName("Unzip")>]
    val unzip: array: ('T1 * 'T2) array -> ('T1 array * 'T2 array)

    /// <summary>Splits an array of triples into three arrays.</summary>
    ///
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The tuple of three arrays.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="unzip3-1">
    /// <code lang="fsharp">
    /// let inputs = [| (1, "one", "I"); (2, "two", "II") |]
    ///
    /// let numbers, names, roman = inputs |> Array.unzip3
    /// </code>
    /// Evaluates <c>numbers</c> to <c>[|1; 2|]</c>, <c>names</c> to <c>[|"one"; "two"|]</c> and <c>roman</c> to <c>[|"I"; "II"|]</c>.
    /// </example>
    [<CompiledName("Unzip3")>]
    val unzip3: array: ('T1 * 'T2 * 'T3) array -> ('T1 array * 'T2 array * 'T3 array)

    /// <summary>Returns a new array containing only the elements of the array
    /// for which the given predicate returns "true".</summary>
    ///
    /// <param name="predicate">The function to test the input elements.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>An array containing the elements for which the given predicate returns true.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <remarks>This is identical to <c>Array.filter</c>.</remarks>
    ///
    /// <example id="where-1">Select only the even numbers:
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.where (fun elm -> elm % 2 = 0)
    /// </code>
    /// Evaluates to <c>[| 2; 4 |]</c>
    /// </example>
    [<CompiledName("Where")>]
    val where: predicate: ('T -> bool) -> array: 'T array -> 'T array

    /// <summary>Returns an array of sliding windows containing elements drawn from the input
    /// array. Each window is returned as a fresh array.</summary>
    ///
    /// <param name="windowSize">The number of elements in each window.</param>
    /// <param name="array">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when windowSize is not positive.</exception>
    ///
    /// <example id="windowed-1">
    /// <code lang="fsharp">
    /// let inputs = [| 1; 2; 3; 4; 5 |]
    ///
    /// inputs |> Array.windowed 3
    /// </code>
    /// Evaluates to <c>[|[|1; 2; 3|]; [|2; 3; 4|]; [|3; 4; 5|]|]</c>
    /// </example>
    [<CompiledName("Windowed")>]
    val windowed: windowSize: int -> array: 'T array -> 'T array array

    /// <summary>Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>The array of tupled elements.</returns>
    ///
    /// <example id="zip-1">
    /// <code lang="fsharp">
    /// let numbers = [|1; 2|]
    /// let names = [|"one"; "two"|]
    ///
    /// Array.zip numbers names
    /// </code>
    /// Evaluates to <c>[| (1, "one"); (2, "two") |]</c>.
    /// </example>
    [<CompiledName("Zip")>]
    val zip: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array

    /// <summary>Combines three arrays into an array of pairs. The three arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
    /// raised.</summary>
    ///
    /// <param name="array1">The first input array.</param>
    /// <param name="array2">The second input array.</param>
    /// <param name="array3">The third input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when any of the input arrays are null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
    ///
    /// <returns>The array of tupled elements.</returns>
    ///
    /// <example id="zip3-1">
    /// <code lang="fsharp">
    /// let numbers = [| 1; 2 |]
    /// let names = [| "one"; "two" |]
    /// let roman = [| "I"; "II" |]
    ///
    /// Array.zip3 numbers names roman
    /// </code>
    /// Evaluates to <c>[|(1, "one", "I"); (2, "two", "II")|]</c>.
    /// </example>
    [<CompiledName("Zip3")>]
    val zip3: array1: 'T1 array -> array2: 'T2 array -> array3: 'T3 array -> ('T1 * 'T2 * 'T3) array

    /// <summary>Return a new array with the item at a given index removed.</summary>
    ///
    /// <param name="index">The index of the item to be removed.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - 1</exception>
    ///
    /// <example id="removeAt-1">
    /// <code>
    /// let inputs = [| 0; 1; 2 |]
    ///
    /// inputs |> Array.removeAt 1
    /// </code>
    /// Evaluates to <c>[| 0; 2 |]</c>.
    /// </example>
    [<CompiledName("RemoveAt")>]
    val removeAt: index: int -> source: 'T array -> 'T array

    /// <summary>Return a new array with the number of items starting at a given index removed.</summary>
    ///
    /// <param name="index">The index of the item to be removed.</param>
    /// <param name="count">The number of items to remove.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - count</exception>
    ///
    /// <example id="removeManyAt-1">
    /// <code>
    /// let inputs = [| 0; 1; 2; 3 |]
    ///
    /// inputs |> Array.removeManyAt 1 2
    /// </code>
    /// Evaluates to <c>[| 0; 3 |]</c>.
    /// </example>
    [<CompiledName("RemoveManyAt")>]
    val removeManyAt: index: int -> count: int -> source: 'T array -> 'T array

    /// <summary>Return a new array with the item at a given index set to the new value.</summary>
    ///
    /// <param name="index">The index of the item to be replaced.</param>
    /// <param name="value">The new value.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is outside 0..source.Length - 1</exception>
    ///
    /// <example id="updateAt-1">
    /// <code>
    /// let inputs = [| 0; 1; 2 |]
    ///
    /// inputs |> Array.updateAt 1 9
    /// </code>
    /// Evaluates to <c>[| 0; 9; 2 |]</c>.
    /// </example>
    [<CompiledName("UpdateAt")>]
    val updateAt: index: int -> value: 'T -> source: 'T array -> 'T array

    /// <summary>Return a new array with a new item inserted before the given index.</summary>
    ///
    /// <param name="index">The index where the item should be inserted.</param>
    /// <param name="value">The value to insert.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is below 0 or greater than source.Length.</exception>
    ///
    /// <example id="insertAt-1">
    /// <code>
    /// let inputs = [| 0; 1; 2 |]
    ///
    /// inputs |> Array.insertAt 1 9
    /// </code>
    /// Evaluates to <c>[| 0; 9; 1; 2 |]</c>.
    /// </example>
    [<CompiledName("InsertAt")>]
    val insertAt: index: int -> value: 'T -> source: 'T array -> 'T array

    /// <summary>Return a new array with new items inserted before the given index.</summary>
    ///
    /// <param name="index">The index where the items should be inserted.</param>
    /// <param name="values">The values to insert.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>A new array (even if values is empty).</returns>
    ///
    /// <exception cref="T:System.ArgumentException">Thrown when index is below 0 or greater than source.Length.</exception>
    ///
    /// <example id="insertManyAt-1">
    /// <code>
    /// let inputs = [| 0; 1; 2 |]
    ///
    /// inputs |> Array.insertManyAt 1 [8; 9]
    /// </code>
    /// Evaluates to <c>[| 0; 8; 9; 1; 2 |]</c>.
    /// </example>
    [<CompiledName("InsertManyAt")>]
    val insertManyAt: index: int -> values: seq<'T> -> source: 'T array -> 'T array

    /// <summary>Return a new array shuffled in a random order.</summary>
    ///
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="randomShuffle-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffle
    /// </code>
    /// Can evaluate to <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffle")>]
    val randomShuffle: source: 'T array -> 'T array

    /// <summary>Return a new array shuffled in a random order with the specified <c>Random</c> instance.</summary>
    ///
    /// <param name="random">The <c>Random</c> instance.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the random argument is null.</exception>
    ///
    /// <example id="randomShuffleWith-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffleWith Random.Shared
    /// </code>
    /// Can evaluate to <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffleWith")>]
    val randomShuffleWith: random: Random -> source: 'T array -> 'T array

    /// <summary>Return a new array shuffled in a random order using the specified <c>randomizer</c> function.</summary>
    ///
    /// <param name="randomizer">The randomizer function, must return a float number from [0.0..1.0) range.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>The result array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the randomizer function returns a value outside the range [0, 1).</exception>
    ///
    /// <example id="randomShuffleBy-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffleBy Random.Shared.NextDouble
    /// </code>
    /// Can evaluate to <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffleBy")>]
    val randomShuffleBy: randomizer: (unit -> float) -> source: 'T array -> 'T array

    /// <summary>Sorts input array in a random order by mutating the array in-place.</summary>
    ///
    /// <param name="source">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="randomShuffleInPlace-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffleInPlace
    /// </code>
    /// After evaluation <c>array</c> can contain <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffleInPlace")>]
    val randomShuffleInPlace: source: 'T array -> unit

    /// <summary>Sorts input array in a random order with the specified <c>Random</c> instance by mutating the array in-place.</summary>
    ///
    /// <param name="source">The input array.</param>
    /// <param name="random">The <c>Random</c> instance.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    ///
    /// <example id="randomShuffleInPlaceWith-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffleInPlaceWith Random.Shared
    /// </code>
    /// After evaluation <c>array</c> can contain <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffleInPlaceWith")>]
    val randomShuffleInPlaceWith: random: Random -> source: 'T array -> unit

    /// <summary>Sorts input array in a random order using the specified <c>randomizer</c> function by mutating the array in-place.</summary>
    ///
    /// <param name="randomizer">The randomizer function, must return a float number from [0.0..1.0) range.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the randomizer function returns a value outside the range [0, 1).</exception>
    ///
    /// <example id="randomShuffleInPlaceBy-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomShuffleInPlaceBy Random.Shared.NextDouble
    /// </code>
    /// After evaluation <c>array</c> can contain <c>[| 0; 2; 4; 3; 1 |]</c>.
    /// </example>
    [<CompiledName("RandomShuffleInPlaceBy")>]
    val randomShuffleInPlaceBy: randomizer: (unit -> float) -> source: 'T array -> unit

    /// <summary>Returns a random element from the given array.</summary>
    ///
    /// <param name="source">The input array.</param>
    ///
    /// <returns>A randomly selected element from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <example id="randomChoice-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoice
    /// </code>
    /// Can evaluate to <c>3</c>.
    /// </example>
    [<CompiledName("RandomChoice")>]
    val randomChoice: source: 'T array -> 'T

    /// <summary>Returns a random element from the given array with the specified <c>Random</c> instance.</summary>
    ///
    /// <param name="random">The <c>Random</c> instance.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>A randomly selected element from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the random argument is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    ///
    /// <example id="randomChoiceWith-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoiceWith Random.Shared
    /// </code>
    /// Can evaluate to <c>3</c>.
    /// </example>
    [<CompiledName("RandomChoiceWith")>]
    val randomChoiceWith: random: Random -> source: 'T array -> 'T

    /// <summary>Returns a random element from the given array using the specified <c>randomizer</c> function.</summary>
    ///
    /// <param name="randomizer">The randomizer function, must return a float number from [0.0..1.0) range.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>A randomly selected element from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the randomizer function returns a value outside the range [0, 1).</exception>
    ///
    /// <example id="randomChoiceBy-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoiceBy Random.Shared.NextDouble
    /// </code>
    /// Can evaluate to <c>3</c>.
    /// </example>
    [<CompiledName("RandomChoiceBy")>]
    val randomChoiceBy: randomizer: (unit -> float) -> source: 'T array -> 'T

    /// <summary>Returns an array of random elements from the given array, each element can be selected multiple times.</summary>
    ///
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    ///
    /// <example id="randomChoices-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoices 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 3 |]</c>.
    /// </example>
    [<CompiledName("RandomChoices")>]
    val randomChoices: count: int -> source: 'T array -> 'T array

    /// <summary>Returns an array of random elements from the given array with the specified <c>Random</c> instance, each element can be selected multiple times.</summary>
    ///
    /// <param name="random">The <c>Random</c> instance.</param>
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the random argument is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    ///
    /// <example id="randomChoicesWith-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoicesWith Random.Shared 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 3 |]</c>.
    /// </example>
    [<CompiledName("RandomChoicesWith")>]
    val randomChoicesWith: random: Random -> count: int -> source: 'T array -> 'T array

    /// <summary>Returns an array of random elements from the given array using the specified <c>randomizer</c> function, each element can be selected multiple times.</summary>
    ///
    /// <param name="randomizer">The randomizer function, must return a float number from [0.0..1.0) range.</param>
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the randomizer function returns a value outside the range [0, 1).</exception>
    ///
    /// <example id="randomChoicesBy-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomChoicesBy Random.Shared.NextDouble 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 3 |]</c>.
    /// </example>
    [<CompiledName("RandomChoicesBy")>]
    val randomChoicesBy: randomizer: (unit -> float) -> count: int -> source: 'T array -> 'T array

    /// <summary>Returns a random sample of elements from the given array, each element can be selected only once.</summary>
    ///
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is greater than the length of the input array.</exception>
    ///
    /// <example id="randomSample-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomSample 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 2 |]</c>.
    /// </example>
    [<CompiledName("RandomSample")>]
    val randomSample: count: int -> source: 'T array -> 'T array

    /// <summary>Returns a random sample of elements from the given array with the specified <c>Random</c> instance, each element can be selected only once.</summary>
    ///
    /// <param name="random">The <c>Random</c> instance.</param>
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentNullException">Thrown when the random argument is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty..</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is greater than the length of the input array.</exception>
    ///
    /// <example id="randomSampleWith-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomSampleWith Random.Shared 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 2 |]</c>.
    /// </example>
    [<CompiledName("RandomSampleWith")>]
    val randomSampleWith: random: Random -> count: int -> source: 'T array -> 'T array

    /// <summary>Returns a random sample of elements from the given array using the specified <c>randomizer</c> function, each element can be selected only once.</summary>
    ///
    /// <param name="randomizer">The randomizer function, must return a float number from [0.0..1.0) range.</param>
    /// <param name="count">The number of elements to return.</param>
    /// <param name="source">The input array.</param>
    ///
    /// <returns>An array of randomly selected elements from the input array.</returns>
    ///
    /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is more than 0 and the input array is empty.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is less than 0.</exception>
    /// <exception cref="T:System.ArgumentException">Thrown when count is greater than the length of the input array.</exception>
    /// <exception cref="T:System.ArgumentOutOfRangeException">Thrown when the randomizer function returns a value outside the range [0, 1).</exception>
    ///
    /// <example id="randomSampleBy-1">
    /// <code lang="fsharp">
    /// let inputs = [| 0; 1; 2; 3; 4 |]
    ///
    /// inputs |> Array.randomSampleBy Random.Shared.NextDouble 3
    /// </code>
    /// Can evaluate to <c>[| 3; 1; 2 |]</c>.
    /// </example>
    [<CompiledName("RandomSampleBy")>]
    val randomSampleBy: randomizer: (unit -> float) -> count: int -> source: 'T array -> 'T array

    /// <summary>Provides parallel operations on arrays </summary>
    module Parallel =

        /// <summary>Tests if all elements of the array satisfy the given predicate.</summary>
        ///
        /// <remarks>The predicate is applied to the elements of the input collection in parallel. If any application
        /// returns false then the overall result is false and testing of other elements in all threads is stopped at system's earliest convenience.
        /// Otherwise, true is returned.</remarks>
        ///
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>True if all of the array elements satisfy the predicate.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-forall-1">
        /// <code lang="fsharp">
        /// let isEven a = a % 2 = 0
        ///
        /// [2; 42] |> Array.Parallel.forall isEven // evaluates to true
        ///
        /// [1; 2] |> Array.Parallel.forall isEven // evaluates to false
        /// </code>
        /// </example>
        [<CompiledName("ForAll")>]
        val forall: predicate: ('T -> bool) -> array: 'T array -> bool

        /// <summary>Tests if any element of the array satisfies the given predicate.</summary>
        ///
        /// <remarks>The predicate is applied to the elements of the input array in parallel. If any application
        /// returns true then the overall result is true and testing of other elements in all threads is stopped at system's earliest convenience.
        /// Otherwise, <c>false</c> is returned.</remarks>
        ///
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>True if any result from <c>predicate</c> is true.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-exists-1">
        /// <code lang="fsharp">
        /// let input = [| 1; 2; 3; 4; 5 |]
        ///
        /// input |> Array.Parallel.exists (fun elm -> elm % 4 = 0)
        /// </code>
        /// Evaluates to <c>true</c>
        /// </example>
        ///
        /// <example id="para-exists-2">
        /// <code lang="fsharp">
        /// let input = [| 1; 2; 3; 4; 5 |]
        ///
        /// input |> Array.Parallel.exists (fun elm -> elm % 6 = 0)
        /// </code>
        /// Evaluates to <c>false</c>
        /// </example>
        [<CompiledName("Exists")>]
        val exists: predicate: ('T -> bool) -> array: 'T array -> bool

        /// <summary>Returns the first element for which the given function returns <c>True</c>.
        /// Returns None if no such element exists.</summary>
        ///
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The first element that satisfies the predicate, or None.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-tryfind-1">Try to find the first even number:
        /// <code lang="fsharp">
        /// let inputs = [| 1; 2; 3 |]
        ///
        /// inputs |> Array.Parallel.tryFind (fun elm -> elm % 2 = 0)
        /// </code>
        /// Evaluates to <c>Some 2</c>.
        /// </example>
        ///
        /// <example id="para-tryfind-2">Try to find the first even number:
        /// <code lang="fsharp">
        /// let inputs = [| 1; 5; 3 |]
        ///
        /// inputs |> Array.Parallel.tryFind (fun elm -> elm % 2 = 0)
        /// </code>
        /// Evaluates to <c>None</c>
        /// </example>
        [<CompiledName("TryFind")>]
        val tryFind: predicate: ('T -> bool) -> array: 'T array -> 'T option

        /// <summary>Returns the index of the first element in the array
        /// that satisfies the given predicate.
        /// Returns <c>None</c> if no such element exists.</summary>
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <returns>The index of the first element that satisfies the predicate, or None.</returns>
        ///
        /// <example id="para-tryfindindex-1">Try to find the index of the first even number:
        /// <code lang="fsharp">
        /// let inputs = [| 1; 2; 3; 4; 5 |]
        ///
        /// inputs |> Array.Parallel.tryFindIndex (fun elm -> elm % 2 = 0)
        /// </code>
        /// Evaluates to <c>Some 1</c>
        /// </example>
        ///
        /// <example id="para-tryfindindex-2">Try to find the index of the first even number:
        /// <code lang="fsharp">
        /// let inputs = [| 1; 3; 5; 7 |]
        ///
        /// inputs |> Array.Parallel.tryFindIndex (fun elm -> elm % 2 = 0)
        /// </code>
        /// Evaluates to <c>None</c>
        /// </example>
        [<CompiledName("TryFindIndex")>]
        val tryFindIndex: predicate: ('T -> bool) -> array: 'T array -> int option

        /// <summary>Applies the given function to successive elements, returning the first
        /// result where the function returns <c>Some(x)</c> for some <c>x</c>. If the function
        /// never returns <c>Some(x)</c> then <c>None</c> is returned.</summary>
        ///
        /// <param name="chooser">The function to transform the array elements into options.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The first transformed element that is <c>Some(x)</c>.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-trypick-1">
        /// <code lang="fsharp">
        /// let input = [| 1; 2; 3 |]
        ///
        /// input |> Array.Parallel.tryPick (fun n -> if n % 2 = 0 then Some (string n) else None)
        /// </code>
        /// Evaluates to <c>Some 2</c>.
        /// </example>
        ///
        /// <example id="para-trypick-2">
        /// <code lang="fsharp">
        /// let input = [| 1; 2; 3 |]
        ///
        /// input |> Array.Parallel.tryPick (fun n -> if n > 3 = 0 then Some (string n) else None)
        /// </code>
        /// Evaluates to <c>None</c>.
        /// </example>
        ///
        [<CompiledName("TryPick")>]
        val tryPick: chooser: ('T -> 'U option) -> array: 'T array -> 'U option

        /// <summary>Applies a function to each element of the array in parallel, threading an accumulator argument
        /// through the computation for each thread involved in the computation. After processing entire input, results from all threads are reduced together.
        /// Raises ArgumentException if the array is empty.</summary>
        /// <remarks>The order of processing is not guaranteed. For that reason, the 'reduce' function argument should be commutative.
        /// (That is, changing the order of execution must not affect the result)
        /// Also, compared to the non-parallel version of Array.reduce, the 'reduce' function may be invoked more times due to the resulting reduction from participating threads.</remarks>
        ///
        /// <param name="reduction">The function to reduce a pair of elements to a single element.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>Result of the reductions.</returns>
        ///
        /// <example id="para-reduce-1">
        /// <code lang="fsharp">
        /// let inputs = [| 1; 3; 4; 2 |]
        ///
        /// inputs |> Array.Parallel.reduce (fun a b -> a + b)
        /// </code>
        /// Evaluates to <c>1 + 3 + 4 + 2</c>. However, the system could have decided to compute (1+3) and (4+2) first, and then put them together.
        /// </example>

        [<CompiledName("Reduce")>]
        val inline reduce: reduction: ('T -> 'T -> 'T) -> array: 'T array -> 'T

        /// <summary>Applies a projection function to each element of the array in parallel, reducing elements in each thread with a dedicated 'reduction' function.
        /// After processing entire input, results from all threads are reduced together.
        /// Raises ArgumentException if the array is empty.</summary>
        /// <remarks>The order of processing is not guaranteed. For that reason, the 'reduction' function argument should be commutative.
        /// (That is, changing the order of execution must not affect the result) </remarks>
        ///
        /// <param name="projection">The function to project from elements of the input array</param>
        /// <param name="reduction">The function to reduce a pair of projected elements to a single element.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>The final result of the reductions.</returns>
        ///
        /// <example id="para-reduceBy-1">
        /// <code lang="fsharp">
        /// let inputs = [| "1"; "3"; "4"; "2" |]
        ///
        /// inputs |> Array.Parallel.reduceBy  (fun x -> int x) (+)
        /// </code>
        /// Evaluates to <c>1 + 3 + 4 + 2</c>. However, the system could have decided to compute (1+3) and (4+2) first, and then put them together.
        /// </example>

        [<CompiledName("ReduceBy")>]
        val reduceBy: projection: ('T -> 'U) -> reduction: ('U -> 'U -> 'U) -> array: 'T array -> 'U

        /// <summary>Returns the greatest of all elements of the array, compared via Operators.max.</summary>
        ///
        /// <remarks>Throws ArgumentException for empty arrays.</remarks>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>The maximum element.</returns>
        ///
        /// <example id="para-max-1">
        /// <code lang="fsharp">
        /// let inputs = [| 10; 12; 11 |]
        ///
        /// inputs |> Array.Parallel.max
        /// </code>
        /// Evaluates to <c>12</c>
        /// </example>
        ///
        /// <example id="para-max-2">
        /// <code lang="fsharp">
        /// let inputs: int array= [| |]
        ///
        /// inputs |> Array.Parallel.max
        /// </code>
        /// Throws <c>System.ArgumentException</c>.
        /// </example>
        [<CompiledName("Max")>]
        val inline max: array: 'T array -> 'T when 'T: comparison

        /// <summary>Returns the greatest of all elements of the array, compared via Operators.max on the function result.</summary>
        ///
        /// <remarks>Throws ArgumentException for empty arrays.</remarks>
        ///
        /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>The maximum element.</returns>
        ///
        /// <example id="para-maxby-1">
        /// <code lang="fsharp">
        /// let inputs = [| "aaa"; "b"; "cccc" |]
        ///
        /// inputs |> Array.Parallel.maxBy (fun s -> s.Length)
        /// </code>
        /// Evaluates to <c>"cccc"</c>
        /// </example>
        ///
        /// <example id="para-maxby-2">
        /// <code lang="fsharp">
        /// let inputs: string array= [| |]
        ///
        /// inputs |> Array.Parallel.maxBy (fun s -> s.Length)
        /// </code>
        /// Throws <c>System.ArgumentException</c>.
        /// </example>
        [<CompiledName("MaxBy")>]
        val inline maxBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison

        /// <summary>Returns the smallest of all elements of the array, compared via Operators.min.</summary>
        ///
        /// <remarks>Throws ArgumentException for empty arrays</remarks>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>The minimum element.</returns>
        ///
        /// <example id="para-min-1">
        /// <code lang="fsharp">
        /// let inputs = [| 10; 12; 11 |]
        ///
        /// inputs |> Array.Parallel.min
        /// </code>
        /// Evaluates to <c>10</c>
        /// </example>
        ///
        /// <example id="min-2">
        /// <code lang="fsharp">
        /// let inputs: int array= [| |]
        ///
        /// inputs |> Array.Parallel.min
        /// </code>
        /// Throws <c>System.ArgumentException</c>.
        /// </example>
        [<CompiledName("Min")>]
        val inline min: array: 'T array -> 'T when 'T: comparison

        /// <summary>Returns the lowest of all elements of the array, compared via Operators.min on the function result.</summary>
        ///
        /// <remarks>Throws ArgumentException for empty arrays.</remarks>
        ///
        /// <param name="projection">The function to transform the elements into a type supporting comparison.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input array is empty.</exception>
        ///
        /// <returns>The minimum element.</returns>
        ///
        /// <example id="para-minby-1">
        /// <code lang="fsharp">
        /// let inputs = [| "aaa"; "b"; "cccc" |]
        ///
        /// inputs |> Array.Parallel.minBy (fun s -> s.Length)
        /// </code>
        /// Evaluates to <c>"b"</c>
        /// </example>
        ///
        /// <example id="para-minby-2">
        /// <code lang="fsharp">
        /// let inputs: string array= [| |]
        ///
        /// inputs |> Array.Parallel.minBy (fun s -> s.Length)
        /// </code>
        /// Throws <c>System.ArgumentException</c>.
        /// </example>
        [<CompiledName("MinBy")>]
        val inline minBy: projection: ('T -> 'U) -> array: 'T array -> 'T when 'U: comparison

        /// <summary>Returns the sum of the elements in the array.</summary>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The resulting sum.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sum-1">
        /// <code lang="fsharp">
        /// let input = [| 1; 5; 3; 2 |]
        ///
        /// input |> Array.Parallel.sum
        /// </code>
        /// Evaluates to <c>11</c>.
        /// </example>
        [<CompiledName("Sum")>]
        val inline sum:
            array: ^T array -> ^T when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member Zero: ^T)

        /// <summary>Returns the sum of the results generated by applying the function to each element of the array.</summary>
        ///
        /// <param name="projection">The function to transform the array elements into the type to be summed.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The resulting sum.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sumby-1">
        /// <code lang="fsharp">
        /// let input = [| "aa"; "bbb"; "cc" |]
        ///
        /// input |> Array.Parallel.sumBy (fun s -> s.Length)
        /// </code>
        /// Evaluates to <c>7</c>.
        /// </example>
        [<CompiledName("SumBy")>]
        val inline sumBy:
            projection: ('T -> ^U) -> array: 'T array -> ^U
                when ^U: (static member (+): ^U * ^U -> ^U) and ^U: (static member Zero: ^U)

        /// <summary>Returns the average of the elements in the array.</summary>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentException">Thrown when <c>array</c> is empty.</exception>
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <returns>The average of the elements in the array.</returns>
        ///
        /// <example id="para-average-1">
        /// <code lang="fsharp">
        /// [| 1.0; 2.0; 6.0 |] |> Array.Parallel.average
        /// </code>
        /// Evaluates to <c>3.0</c>
        /// </example>
        ///
        /// <example id="para-average-2">
        /// <code lang="fsharp">
        /// [| |] |> Array.Parallel.average
        /// </code>
        /// Throws <c>ArgumentException</c>
        /// </example>
        [<CompiledName("Average")>]
        val inline average:
            array: ^T array -> ^T
                when ^T: (static member (+): ^T * ^T -> ^T) and ^T: (static member DivideByInt: ^T * int -> ^T)

        /// <summary>Returns the average of the elements generated by applying the function to each element of the array.</summary>
        ///
        /// <param name="projection">The function to transform the array elements before averaging.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentException">Thrown when <c>array</c> is empty.</exception>
        ///
        /// <returns>The computed average.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-average-by-1">
        /// <code lang="fsharp">
        /// type Foo = { Bar: float }
        ///
        /// let input = [| {Bar = 2.0}; {Bar = 4.0} |]
        ///
        /// input |> Array.Parallel.averageBy (fun foo -> foo.Bar)
        /// </code>
        /// Evaluates to <c>3.0</c>
        /// </example>
        ///
        /// <example id="para-average-by-2">
        /// <code lang="fsharp">
        /// type Foo = { Bar: float }
        ///
        /// let input : Foo array = [| |]
        ///
        /// input |> Array.Parallel.averageBy (fun foo -> foo.Bar)
        /// </code>
        /// Throws <c>ArgumentException</c>
        /// </example>
        [<CompiledName("AverageBy")>]
        val inline averageBy:
            projection: ('T -> ^U) -> array: 'T array -> ^U
                when ^U: (static member (+): ^U * ^U -> ^U) and ^U: (static member DivideByInt: ^U * int -> ^U)

        /// <summary>Apply the given function to each element of the array. Return
        /// the array comprised of the results <c>x</c> for each element where
        /// the function returns <c>Some(x)</c>.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="chooser">The function to generate options from the elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The array of results.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="choose-1">
        /// <code lang="fsharp">
        /// let input = [| Some 1; None; Some 2 |]
        ///
        /// input |> Array.Parallel.choose id
        /// </code>
        /// Evaluates to <c>[| 1; 2 |]</c>
        /// </example>
        ///
        /// <example id="choose-2">
        /// <code lang="fsharp">
        /// let input = [| 1; 2; 3 |]
        ///
        /// input |> Array.Parallel.choose (fun n -> if n % 2 = 0 then Some n else None)
        /// </code>
        /// Evaluates to <c>[| 2 |]</c>
        /// </example>
        [<CompiledName("Choose")>]
        val choose: chooser: ('T -> 'U option) -> array: 'T array -> 'U array

        /// <summary>For each element of the array, apply the given function. Concatenate all the results and return the combined array.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="mapping"></param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>'U array</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="collect-1">
        /// <code lang="fsharp">
        /// type Foo = { Bar: int array }
        ///
        /// let input = [| {Bar = [| 1; 2 |]}; {Bar = [| 3; 4 |]} |]
        ///
        /// input |> Array.Parallel.collect (fun foo -> foo.Bar)
        /// </code>
        /// Evaluates to <c>[| 1; 2; 3; 4 |]</c>
        /// </example>
        ///
        /// <example id="collect-2">
        /// <code lang="fsharp">
        /// let input = [| [| 1; 2 |]; [| 3; 4 |] |]
        ///
        /// input |> Array.Parallel.collect id
        /// </code>
        /// Evaluates to <c>[| 1; 2; 3; 4 |]</c>
        /// </example>
        [<CompiledName("Collect")>]
        val collect: mapping: ('T -> 'U array) -> array: 'T array -> 'U array

        /// <summary>Build a new array whose elements are the results of applying the given function
        /// to each of the elements of the array.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="mapping"></param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The array of results.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="map-1">
        /// <code lang="fsharp">
        /// let inputs = [| "a"; "bbb"; "cc" |]
        ///
        /// inputs |> Array.Parallel.map (fun x -> x.Length)
        /// </code>
        /// Evaluates to <c>[| 1; 3; 2 |]</c>
        /// </example>
        [<CompiledName("Map")>]
        val map: mapping: ('T -> 'U) -> array: 'T array -> 'U array

        /// <summary>Build a new array whose elements are the results of applying the given function
        /// to each of the elements of the array. The integer index passed to the
        /// function indicates the index of element being transformed.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="mapping"></param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The array of results.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="mapi-1">
        /// <code lang="fsharp">
        /// let inputs = [| 10; 10; 10 |]
        ///
        /// inputs |> Array.Parallel.mapi (fun i x -> i + x)
        /// </code>
        /// Evaluates to <c>[| 10; 11; 12 |]</c>
        /// </example>
        [<CompiledName("MapIndexed")>]
        val mapi: mapping: (int -> 'T -> 'U) -> array: 'T array -> 'U array

        /// <summary>Applies a key-generating function to each element of an array in parallel and yields an array of
        /// unique keys. Each unique key contains an array of all elements that match
        /// to this key.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.
        /// The order of the keys and values in the result is also not specified</remarks>
        /// <param name="projection">A function that transforms an element of the array into a comparable key.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The result array.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="group-by-para-1">
        /// <code lang="fsharp">
        /// let inputs = [| 1; 2; 3; 4; 5 |]
        ///
        /// inputs |> Array.Parallel.groupBy (fun n -> n % 2)
        /// </code>
        /// Evaluates to <c>[| (1, [| 1; 3; 5 |]); (0, [| 2; 4 |]) |]</c>
        /// </example>

        [<CompiledName("GroupBy")>]
        val groupBy: projection: ('T -> 'Key) -> array: 'T array -> ('Key * 'T array) array when 'Key: equality

        /// <summary>Apply the given function to each element of the array. </summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="action"></param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="iter-1">
        /// <code lang="fsharp">
        /// let inputs = [| "a"; "b"; "c" |]
        ///
        /// inputs |> Array.Parallel.iter (printfn "%s")
        /// </code>
        /// Evaluates to <c>unit</c> and prints the following to the console in an unspecified order:
        /// <code>
        /// a
        /// c
        /// b
        /// </code>
        /// </example>
        [<CompiledName("Iterate")>]
        val iter: action: ('T -> unit) -> array: 'T array -> unit

        /// <summary>Apply the given function to each element of the array. The integer passed to the
        /// function indicates the index of element.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to elements of the input array is not specified.</remarks>
        ///
        /// <param name="action"></param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="iteri-1">
        /// <code lang="fsharp">
        /// let inputs = [| "a"; "b"; "c" |]
        ///
        /// inputs |> Array.Parallel.iteri (fun i v -> printfn "{i}: {v}")
        /// </code>
        /// Evaluates to <c>unit</c> and prints the following to the console in an unspecified order:
        /// <code>
        /// 0: a
        /// 2: c
        /// 1: b
        /// </code>
        /// </example>
        [<CompiledName("IterateIndexed")>]
        val iteri: action: (int -> 'T -> unit) -> array: 'T array -> unit

        /// <summary>Create an array given the dimension and a generator function to compute the elements.</summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to indices is not specified.</remarks>
        ///
        /// <param name="count"></param>
        /// <param name="initializer"></param>
        ///
        /// <returns>The array of results.</returns>
        ///
        /// <example id="init-1">
        /// <code lang="fsharp">
        /// Array.Parallel.init 4 (fun v -> v + 5)
        /// </code>
        /// Evaluates to <c>[| 5; 6; 7; 8 |]</c>
        /// </example>
        [<CompiledName("Initialize")>]
        val init: count: int -> initializer: (int -> 'T) -> 'T array

        /// <summary>Split the collection into two collections, containing the
        /// elements for which the given predicate returns "true" and "false"
        /// respectively </summary>
        ///
        /// <remarks>Performs the operation in parallel using <see cref="M:System.Threading.Tasks.Parallel.For" />.
        /// The order in which the given function is applied to indices is not specified.</remarks>
        ///
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The two arrays of results.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="partition-1">
        /// <code lang="fsharp">
        /// let inputs = [| 1; 2; 3; 4 |]
        ///
        /// inputs |> Array.Parallel.partition (fun x -> x % 2 = 0)
        /// </code>
        /// Evaluates to <c>([|2; 4|], [|1; 3|])</c>.
        /// </example>
        [<CompiledName("Partition")>]
        val partition: predicate: ('T -> bool) -> array: 'T array -> 'T array * 'T array

        /// <summary>Sorts the elements of an array in parallel, returning a new array. Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>. </summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The sorted array.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sort-1">
        /// <code lang="fsharp">
        /// let input = [| 8; 4; 3; 1; 6; 1 |]
        ///
        /// Array.Parallel.sort input
        /// </code>
        /// Evaluates to <c>[| 1; 1 3; 4; 6; 8 |]</c>.
        /// </example>
        [<CompiledName("Sort")>]
        val sort: array: 'T array -> 'T array when 'T: comparison

        /// <summary>Sorts the elements of an array in parallel, using the given projection for the keys and returning a new array.
        /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="projection">The function to transform array elements into the type that is compared.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The sorted array.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sortby-1">
        /// <code lang="fsharp">
        /// let input = [| "a"; "bbb"; "cccc"; "dd" |]
        ///
        /// input |> Array.Parallel.sortBy (fun s -> s.Length)
        /// </code>
        /// Evaluates to <c>[|"a"; "dd"; "bbb"; "cccc"|]</c>.
        /// </example>

        [<CompiledName("SortBy")>]
        val sortBy: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison

        /// <summary>Sorts the elements of an array in parallel, using the given comparison function as the order, returning a new array.</summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="comparer">The function to compare pairs of array elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The sorted array.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sortwith-1">Sort an array of pairs using a comparison function that compares string lengths then index numbers:
        /// <code lang="fsharp">
        /// let compareEntries (n1: int, s1: string) (n2: int, s2: string) =
        ///     let c = compare s1.Length s2.Length
        ///     if c &lt;> 0 then c else
        ///     compare n1 n2
        ///
        /// let input = [| (0,"aa"); (1,"bbb"); (2,"cc"); (3,"dd") |]
        ///
        /// input |> Array.Parallel.sortWith compareEntries
        /// </code>
        /// Evaluates to <c>[|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]</c>.
        /// </example>
        [<CompiledName("SortWith")>]
        val sortWith: comparer: ('T -> 'T -> int) -> array: 'T array -> 'T array

        /// <summary>Sorts the elements of an array by mutating the array in-place in parallel, using the given projection for the keys.
        /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="projection">The function to transform array elements into the type that is compared.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sortinplaceby-1">
        /// <code lang="fsharp">
        /// let array = [| "a"; "bbb"; "cccc"; "dd" |]
        ///
        /// array |> Array.Parallel.sortInPlaceBy (fun s -> s.Length)
        /// </code>
        /// After evaluation <c>array</c> contains <c>[|"a"; "dd"; "bbb"; "cccc"|]</c>.
        /// </example>
        [<CompiledName("SortInPlaceBy")>]
        val sortInPlaceBy: projection: ('T -> 'Key) -> array: 'T array -> unit when 'Key: comparison

        /// <summary>Sorts the elements of an array by mutating the array in-place in parallel, using the given comparison function as the order.</summary>
        ///
        /// <param name="comparer">The function to compare pairs of array elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sortinplacewith-1"> The following sorts entries using a comparison function that compares string lengths then index numbers:
        /// <code lang="fsharp">
        /// let compareEntries (n1: int, s1: string) (n2: int, s2: string) =
        ///     let c = compare s1.Length s2.Length
        ///     if c &lt;> 0 then c else
        ///     compare n1 n2
        ///
        /// let array = [| (0,"aa"); (1,"bbb"); (2,"cc"); (3,"dd") |]
        ///
        /// array |> Array.Parallel.sortInPlaceWith compareEntries
        /// </code>
        /// After evaluation <c>array</c> contains <c>[|(0, "aa"); (2, "cc"); (3, "dd"); (1, "bbb")|]</c>.
        /// </example>
        [<CompiledName("SortInPlaceWith")>]
        val sortInPlaceWith: comparer: ('T -> 'T -> int) -> array: 'T array -> unit

        /// <summary>Sorts the elements of an array by mutating the array in-place in parallel, using the given comparison function.
        /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is null.</exception>
        ///
        /// <example id="para-sortinplace-1">
        /// <code lang="fsharp">
        /// let array = [| 8; 4; 3; 1; 6; 1 |]
        ///
        /// Array.sortInPlace array
        /// </code>
        /// After evaluation <c>array</c> contains <c>[| 1; 1; 3; 4; 6; 8 |]</c>.
        /// </example>
        [<CompiledName("SortInPlace")>]
        val sortInPlace: array: 'T array -> unit when 'T: comparison

        /// <summary>Sorts the elements of an array in parallel, in descending order, returning a new array. Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>. </summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The sorted array.</returns>
        ///
        /// <example id="para-sortdescending-1">
        /// <code lang="fsharp">
        /// let input = [| 8; 4; 3; 1; 6; 1 |]
        ///
        /// input |> Array.Parallel.sortDescending
        /// </code>
        /// Evaluates to <c>[| 8; 6; 4; 3; 1; 1 |]</c>.
        /// </example>
        [<CompiledName("SortDescending")>]
        val sortDescending: array: 'T array -> 'T array when 'T: comparison

        /// <summary>Sorts the elements of an array in parallel, in descending order, using the given projection for the keys and returning a new array.
        /// Elements are compared using <see cref="M:Microsoft.FSharp.Core.Operators.compare"/>.</summary>
        ///
        /// <remarks>This is not a stable sort, i.e. the original order of equal elements is not necessarily preserved.
        /// For a stable sort, consider using <see cref="M:Microsoft.FSharp.Collections.SeqModule.Sort"/>.</remarks>
        ///
        /// <param name="projection">The function to transform array elements into the type that is compared.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>The sorted array.</returns>
        ///
        /// <example id="para-sortbydescending-1">
        /// <code lang="fsharp">
        /// let input = [| "a"; "bbb"; "cccc"; "dd" |]
        ///
        /// input |> Array.Parallel.sortByDescending (fun s -> s.Length)
        /// </code>
        /// Evaluates to <c>[|"cccc"; "bbb"; "dd"; "a"|]</c>.
        /// </example>
        [<CompiledName("SortByDescending")>]
        val sortByDescending: projection: ('T -> 'Key) -> array: 'T array -> 'T array when 'Key: comparison

        /// <summary>Combines the two arrays into an array of pairs. The two arrays must have equal lengths, otherwise an <c>ArgumentException</c> is
        /// raised.</summary>
        ///
        /// <param name="array1">The first input array.</param>
        /// <param name="array2">The second input array.</param>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when either of the input arrays is null.</exception>
        /// <exception cref="T:System.ArgumentException">Thrown when the input arrays differ in length.</exception>
        ///
        /// <returns>The array of tupled elements.</returns>
        ///
        /// <example id="para-zip-1">
        /// <code lang="fsharp">
        /// let numbers = [|1; 2|]
        /// let names = [|"one"; "two"|]
        ///
        /// Array.Parallel.zip numbers names
        /// </code>
        /// Evaluates to <c>[| (1, "one"); (2, "two") |]</c>.
        /// </example>
        [<CompiledName("Zip")>]
        val zip: array1: 'T1 array -> array2: 'T2 array -> ('T1 * 'T2) array

        /// <summary>Returns a new collection containing only the elements of the collection
        /// for which the given predicate returns <c>true</c>.</summary>
        ///
        /// <param name="predicate">The function to test the input elements.</param>
        /// <param name="array">The input array.</param>
        ///
        /// <returns>An array containing the elements for which the given predicate returns true.</returns>
        ///
        /// <exception cref="T:System.ArgumentNullException">Thrown when the input array is <c>null</c>.</exception>
        ///
        /// <example id="para-filter-1">
        /// <code lang="fsharp">
        /// let inputs = [| 1; 2; 3; 4 |]
        ///
        /// inputs |> Array.Parallel.filter (fun elm -> elm % 2 = 0)
        /// </code>
        /// Evaluates to <c>[| 2; 4 |]</c>
        /// </example>
        [<CompiledName("Filter")>]
        val filter: predicate: ('T -> bool) -> array: 'T array -> 'T array
